Mercurial > hg > CbC > old > device
diff mc-code-ia32.c @ 365:5ac17fa9d7e0
bit-field constant assignment
author | kono |
---|---|
date | Wed, 07 Jul 2004 14:34:25 +0900 |
parents | c29eebf3eaf4 |
children | 2d510935c37d |
line wrap: on
line diff
--- a/mc-code-ia32.c Tue Jul 06 17:55:40 2004 +0900 +++ b/mc-code-ia32.c Wed Jul 07 14:34:25 2004 +0900 @@ -1286,6 +1286,9 @@ } else if (ret_type==VOID) { regv[freg]=0; regv[creg]=0; } else { + if (!is_int_reg(creg)) { + lreg=0; creg=virtual(REG_EAX); + } use_register(creg,REG_EAX,0); fregv[freg]=0; regv[creg]=1; } @@ -3460,6 +3463,80 @@ } } + +static void +make_mask_and_or_const(int mask,int reg,int c) +{ + int a; +// printf("# mask 0x%08x ~0x%08x\n",mask,~mask); + a = ~mask|c; + if (a!=-1) { + /* do conjunction */ + if (rname[reg]<MAX_DATA_REG && ((a& ~0xffff)==~0xffff)) { + if ((a& ~0xff)==~0xff) + printf("\tandb $%d,%s\n",a&0xff,register_name(reg,1)); + else + printf("\tandw $%d,%s\n",a&0xffff,register_name(reg,2)); + } else + printf("\tandl $%d,%s\n",a,register_name(reg,0)); + } + /* make or-mask */ + c = mask&c; + if (c!=0) { + /* do disjunction */ + if (rname[reg]<MAX_DATA_REG && (!(c& ~0xffff))) { + if (!(c& ~0xff)) + printf("\torb $%d,%s\n",c&0xff,register_name(reg,1)); + else + printf("\torw $%d,%s\n",c&0xffff,register_name(reg,2)); + } else + printf("\torl $%d,%s\n",c,register_name(reg,0)); + } +} + +extern void +code_bit_replace_const(int value,int lvalue,int type,int bitpos) +{ + int sign,bitsz,l,align; + int bitsize = cadddr(type); + int mask = 0; + int c; +#if LONGLONG_CODE + long long lc; +#endif + set_bitsz(type,&sign,&bitsz,&align,&l); +// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); + if (l) { +#if LONGLONG_CODE + use_longlong(lvalue); + /* shift left */ + lc = lcadr(value); + lc <<= bitpos; + if (bitpos+bitsize>=32) { + /* make and-mask upper */ + mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31); + make_mask_and_or_const(mask, + virtual(lvalue==REG_L?REG_EDI:REG_EDX),(int)(lc>>32)); + } + if (bitpos<32) { + /* make and-mask lower */ + mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); + make_mask_and_or_const(mask, + virtual(lvalue==REG_L?REG_ESI:REG_EAX),(int)(lc)); + } +#endif + } else { + use_int(lvalue); + /* shift left */ + c = cadr(value); + c <<= bitpos; + /* make and-mask */ + mask = make_mask(32-bitpos-bitsize,31-bitpos); + make_mask_and_or_const(mask,lvalue,c); + } +} + + #endif /* end */