# HG changeset patch # User kono # Date 1087978353 -32400 # Node ID fa4c7b15d7ed6e609592a7442844abd4856d52e0 # Parent 4c8f8ef8c0cf12cd0088721dfd512b23b555fd13 bit field all code written diff -r 4c8f8ef8c0cf -r fa4c7b15d7ed mc-code-powerpc.c --- 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