Mercurial > hg > CbC > old > device
changeset 330:fa4c7b15d7ed
bit field all code written
author | kono |
---|---|
date | Wed, 23 Jun 2004 17:12:33 +0900 |
parents | 4c8f8ef8c0cf |
children | f25aa4f03198 |
files | mc-code-powerpc.c |
diffstat | 1 files changed, 59 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-powerpc.c Wed Jun 23 16:10:03 2004 +0900 +++ b/mc-code-powerpc.c Wed Jun 23 17:12:33 2004 +0900 @@ -5178,29 +5178,76 @@ /* bit field replacement */ +static int +make_mask(int from,int to) +{ + int mask = 0; + int bit = 1; + int i; + if (from<0||from>32) error(-1); + for (i=31;from<=i;i--,bit<<1) { + if (i<=to) { + mask |= bit; + } + } +} + +static void +make_mask_and_or(int mask,int tmp,char *trn,*crn,*lrn) +{ + code_const(~mask,tmp); + printf("\tor %s,%s,%s\n",trn,crn,trn); + /* do conjunction */ + printf("\tand %s,%s,%s\n",lrn,trn,lrn); + /* make or-mask */ + code_const(mask,tmp); + printf("\tand %s,%s,%s\n",trn,crn,trn); + /* do disjunction */ + printf("\tor %s,%s,%s\n",lrn,trn,lrn); +} + extern void code_bit_replace(int value,int lvalue,int type,int bit_offset) { int sign,bitsz,l; int bitsize = cadddr(type); + int mask = 0; + int tmp = -1; + char *crn,*lrn,*trn; set_bitsz(type,&sign,&bitsz,&l); if (l) { - use_longlong(reg); - /* make and-mask lower */ - /* make and-mask upper */ - /* make or-mask lower */ - /* make or-mask upper */ + use_longlong(value); + crn = lregister_name_low(value); + lrn = lregister_name_low(lvalue); /* shift left */ - /* do conjunction */ - /* do disjunction */ + if ((i=bitsz-bitsize-bitpos)) + loprtc(LLSHIFT,reg,i); + trn = register_name(tmp = get_register()); + if (bitpos+bitsize>32) { + /* make and-mask lower */ + mask = make_mask(bitpos>32?bitpos-32:0,bitpos+bitsize-32); + make_mask_and_or(mask,tmp,trn,crn,lrn); + } + crn = lregister_name_high(value); + lrn = lregister_name_high(lvalue); + if (bitpos<32) { + /* make and-mask upper */ + mask = make_mask(bitpos,bitpos+bitsize>32?31:bitpos+bitsize); + make_mask_and_or(mask,tmp,trn,crn,lrn); + } } else { - use_int(reg); + use_int(value); + crn = register_name(value); + lrn = register_name(lvalue); + /* shift left */ + if ((i=bitsz-bitsize-bitpos)) + oprtc(LSHIFT,reg,i); + trn = register_name(tmp = get_register()); /* make and-mask */ - /* make or-mask */ - /* shift left */ - /* do conjunction */ - /* do disjunction */ + mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize); + make_mask_and_or(mask,tmp,trn,crn,lrn); } + if (tmp!=-1) free_register(tmp); } #endif