Mercurial > hg > CbC > old > device
comparison mc-code-arm.c @ 429:7733da111bd6
arm register usage
author | kono |
---|---|
date | Sat, 30 Oct 2004 22:25:27 +0900 |
parents | 7851023f5af1 |
children | ba5faa547607 |
comparison
equal
deleted
inserted
replaced
428:61c77ff18023 | 429:7733da111bd6 |
---|---|
127 int MAX_CODE_INPUT_FREGISTER_VAR = 6; | 127 int MAX_CODE_INPUT_FREGISTER_VAR = 6; |
128 | 128 |
129 #define LREG_V 3 /* mark for virtual long long/double register */ | 129 #define LREG_V 3 /* mark for virtual long long/double register */ |
130 #define REGS_MAX (REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_LREGISTER+LREG_V) | 130 #define REGS_MAX (REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_LREGISTER+LREG_V) |
131 static int arm_regs[REGS_MAX]; | 131 static int arm_regs[REGS_MAX]; |
132 static int regs_use[REGS_MAX]; | |
132 static int regv_h0[REAL_MAX_LREGISTER+LREG_V]; | 133 static int regv_h0[REAL_MAX_LREGISTER+LREG_V]; |
133 static int regv_l0[REAL_MAX_LREGISTER+LREG_V]; | 134 static int regv_l0[REAL_MAX_LREGISTER+LREG_V]; |
134 #define regv_h(i) regv_h0[(i)-LREG_OFFSET] | 135 #define regv_h(i) regv_h0[(i)-LREG_OFFSET] |
135 #define regv_l(i) regv_l0[(i)-LREG_OFFSET] | 136 #define regv_l(i) regv_l0[(i)-LREG_OFFSET] |
136 | 137 |
561 } | 562 } |
562 | 563 |
563 void | 564 void |
564 code_gexpr(int e){ | 565 code_gexpr(int e){ |
565 if (is_int_reg(creg) && creg!=ireg) error(-1); | 566 if (is_int_reg(creg) && creg!=ireg) error(-1); |
566 // register_usage("code_gexpr"); | 567 register_usage("code_gexpr"); |
567 } | 568 } |
568 | 569 |
569 | 570 |
570 void | 571 void |
571 code_arg_register(NMTBL *fnptr) | 572 code_arg_register(NMTBL *fnptr) |
1164 } | 1165 } |
1165 } | 1166 } |
1166 return list2(LVAR,new_lvar(d?SIZE_OF_DOUBLE:SIZE_OF_FLOAT)); | 1167 return list2(LVAR,new_lvar(d?SIZE_OF_DOUBLE:SIZE_OF_FLOAT)); |
1167 } | 1168 } |
1168 | 1169 |
1169 void | 1170 int |
1170 | |
1171 emit_push() | 1171 emit_push() |
1172 { | 1172 { |
1173 int new_reg; | 1173 int new_reg,old; |
1174 if (!is_int_reg(creg)) error(-1); | 1174 if (!is_int_reg(creg)) error(-1); |
1175 if (reg_sp>MAX_MAX) error(-1); | 1175 if (reg_sp>MAX_MAX) error(-1); |
1176 new_reg = get_register(); /* 絶対に取れる */ | 1176 new_reg = get_register(); /* 絶対に取れる */ |
1177 reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ | 1177 reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ |
1178 ireg = creg = new_reg; | 1178 ireg = creg = new_reg; |
1179 return old; | |
1179 } | 1180 } |
1180 | 1181 |
1181 int | 1182 int |
1182 emit_pop(int type) | 1183 emit_pop(int type) |
1183 { | 1184 { |
2226 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: | 2227 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: |
2227 case DDIV: case DADD: case DSUB: case DMUL: case DMINUS: | 2228 case DDIV: case DADD: case DSUB: case DMUL: case DMINUS: |
2228 case DPOSTINC : case DPREINC : case DASSOP : | 2229 case DPOSTINC : case DPREINC : case DASSOP : |
2229 case DOP+LT : case DOP+LE : case DOP+GT : case DOP+GE : | 2230 case DOP+LT : case DOP+LE : case DOP+GT : case DOP+GE : |
2230 case DOP+EQ : case DOP+NEQ: | 2231 case DOP+EQ : case DOP+NEQ: |
2232 case RBIT_FIELD: case BASS: case BASSOP: | |
2231 return 1; | 2233 return 1; |
2232 } | 2234 } |
2233 return 0; | 2235 return 0; |
2234 } | 2236 } |
2235 | 2237 |
2466 int reg_arg_list=0,ret_type,special_lvar; | 2468 int reg_arg_list=0,ret_type,special_lvar; |
2467 NMTBL *fn = 0; | 2469 NMTBL *fn = 0; |
2468 int jmp = 0; | 2470 int jmp = 0; |
2469 int complex_; | 2471 int complex_; |
2470 int pnargs,preg_arg,pfreg_arg; | 2472 int pnargs,preg_arg,pfreg_arg; |
2471 int stargs; | 2473 int stargs,i; |
2472 int half_register = 0; | 2474 int half_register = 0; |
2473 | 2475 |
2474 special_lvar = -1; | 2476 special_lvar = -1; |
2475 ret_type = cadr(cadddr(e1)); | 2477 ret_type = cadr(cadddr(e1)); |
2476 if (ret_type==CHAR) ret_type=INT; // ??? | 2478 if (ret_type==CHAR) ret_type=INT; // ??? |
2652 arg = car(reg_arg_list); | 2654 arg = car(reg_arg_list); |
2653 if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER | 2655 if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER |
2654 ||car(arg)==LREGISTER) | 2656 ||car(arg)==LREGISTER) |
2655 free_register(cadr(arg)); | 2657 free_register(cadr(arg)); |
2656 else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); | 2658 else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); |
2659 } | |
2660 for(i=1;i<MAX_INPUT_REGISTER_VAR;i++) { | |
2661 free_register(i); | |
2657 } | 2662 } |
2658 if (ret_type==DOUBLE) { | 2663 if (ret_type==DOUBLE) { |
2659 set_dreg(RET_DREGISTER,0); | 2664 set_dreg(RET_DREGISTER,0); |
2660 use_reg(RET_DREGISTER); | 2665 use_reg(RET_DREGISTER); |
2661 } else if (ret_type==FLOAT) { | 2666 } else if (ret_type==FLOAT) { |
5855 #if BIT_FIELD_CODE | 5860 #if BIT_FIELD_CODE |
5856 | 5861 |
5857 /* bit field alignment calcuration */ | 5862 /* bit field alignment calcuration */ |
5858 | 5863 |
5859 static void | 5864 static void |
5860 set_bitsz(int type,int *psign,int *pbitsz,int *palign,int *pl) | 5865 set_bitsz(int type,int *pbitpos, int *pbitsize, |
5866 int *psign,int *pbitsz,int *palign,int *pl) | |
5861 { | 5867 { |
5862 int sign=0,bitsz; | 5868 int sign=0,bitsz; |
5863 int align,l=0; | 5869 int align,l=0; |
5870 *pbitpos = cadr(caddr(type)); | |
5871 *pbitsize = caddr(caddr(type)); | |
5864 switch(cadr(type)) { /* value type */ | 5872 switch(cadr(type)) { /* value type */ |
5865 case INT: sign=1; break; | 5873 case INT: sign=1; break; |
5866 case UNSIGNED: break; | 5874 case UNSIGNED: break; |
5867 case CHAR: sign=1; break; | 5875 case CHAR: sign=1; break; |
5868 case UCHAR: break; | 5876 case UCHAR: break; |
5906 int sign,bitsz,align; | 5914 int sign,bitsz,align; |
5907 int i; | 5915 int i; |
5908 int bitpos = *bfd; | 5916 int bitpos = *bfd; |
5909 int offset = *poffset; | 5917 int offset = *poffset; |
5910 int l; | 5918 int l; |
5911 int bitsize = caddr(caddr(type)); | 5919 int bitsize,bitpos0; |
5912 set_bitsz(type,&sign,&bitsz,&align,&l); | 5920 set_bitsz(type,&bitpos0,&bitsize,&sign,&bitsz,&align,&l); |
5913 | 5921 |
5914 if (bitsize>bitsz) { error(BTERR); bitsize = i; } | 5922 if (bitsize>bitsz) { error(BTERR); bitsize = i; } |
5915 | 5923 |
5916 /* bfd means previous bit field bit offset */ | 5924 /* bfd means previous bit field bit offset */ |
5917 if (bitpos) { | 5925 if (bitpos) { |
5954 /* alignment is correct and space remains */ | 5962 /* alignment is correct and space remains */ |
5955 *poffset=offset=i; | 5963 *poffset=offset=i; |
5956 i = l+bitsize; | 5964 i = l+bitsize; |
5957 *bfd = (i==bitsz)?0:i; | 5965 *bfd = (i==bitsz)?0:i; |
5958 *sz = (i+7)/8; | 5966 *sz = (i+7)/8; |
5959 printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); | 5967 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); |
5960 return l; | 5968 return l; |
5961 } | 5969 } |
5962 } | 5970 } |
5963 } | 5971 } |
5964 | 5972 |
5969 } | 5977 } |
5970 bitpos = 0; | 5978 bitpos = 0; |
5971 *bfd = (bitsize==bitsz)?0:bitsize; | 5979 *bfd = (bitsize==bitsz)?0:bitsize; |
5972 *sz = (bitsize+7)/8; | 5980 *sz = (bitsize+7)/8; |
5973 | 5981 |
5974 printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); | 5982 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); |
5975 return bitpos; | 5983 return bitpos; |
5976 } | 5984 } |
5977 | 5985 |
5978 /* bit field value */ | 5986 /* bit field value */ |
5979 | 5987 |
5980 /* reg contains container value, result should be in reg */ | 5988 /* reg contains container value, result should be in reg */ |
5981 extern void | 5989 extern void |
5982 code_bit_field(int type,int bitpos,int reg) | 5990 code_bit_field(int type,int adr,int reg) |
5983 { | 5991 { |
5984 int sign,bitsz,l,align; | 5992 int sign,bitsz,l,align; |
5985 int bitsize = caddr(caddr(type)); | 5993 int bitsize,bitpos; |
5986 int i; | 5994 int i,size,adhoc=-1; |
5987 set_bitsz(type,&sign,&bitsz,&align,&l); | 5995 set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); |
5996 size = bitsz/8; | |
5988 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); | 5997 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); |
5989 /* this implementation returns -1 for int i:1; */ | 5998 /* this implementation returns -1 for int i:1; */ |
5990 if (l==1) { | 5999 if (l==1) { |
6000 use_int(adr); | |
5991 use_longlong(reg); | 6001 use_longlong(reg); |
6002 lload(adr,reg,0); | |
5992 /* shift left */ | 6003 /* shift left */ |
5993 if ((i=bitsz-bitsize-bitpos)) | 6004 if ((i=bitsz-bitsize-bitpos)) |
5994 loprtc(LLSHIFT,reg,list2(CONST,i)); | 6005 loprtc(LLSHIFT,reg,list2(CONST,i)); |
5995 /* shift right */ | 6006 /* shift right */ |
5996 if ((i=bitsz-bitsize)) | 6007 if ((i=bitsz-bitsize)) |
5997 loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); | 6008 loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); |
5998 } else if (l==2) { | 6009 } else if (l==2) { |
5999 use_int(reg); | 6010 use_int(adr); |
6000 lreg = get_lregister(); | 6011 use_longlong(reg); |
6001 /* | 6012 /* |
6002 | 6013 |
6003 <-----bitsize---------------> | 6014 <-----bitsize---------------> |
6004 hhhhhh mmmmmmmmmmmm lllllll | 6015 hhhhhh mmmmmmmmmmmm lllllll |
6005 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh | 6016 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh |
6011 rest >> = b; | 6022 rest >> = b; |
6012 rest << = a; (b>a) ==> rest >> (b-a) | 6023 rest << = a; (b>a) ==> rest >> (b-a) |
6013 (64+32-bitsize -bitpos - (bitsz-bitsize)) | 6024 (64+32-bitsize -bitpos - (bitsz-bitsize)) |
6014 = 64+32 -bitsz -bitbpos | 6025 = 64+32 -bitsz -bitbpos |
6015 */ | 6026 */ |
6027 if (adr==regv_h(reg)||adr==regv_l(reg)) { | |
6028 // adhoc = get_register(); adhoc=1; | |
6029 // code_register(adr,adhoc); | |
6030 } | |
6016 /* load hhhhh */ | 6031 /* load hhhhh */ |
6017 code_ld(cload(0,0),regv_h(lreg),SIZE_OF_INT*2,reg,cext_at(0,0)); | 6032 code_ld(cload(0,0),regv_h(reg),SIZE_OF_INT*2,adr,cext_at(0,0)); |
6018 /* load mmmmmm */ | 6033 /* load mmmmmm */ |
6019 code_ld(cload(0,0),regv_l(lreg),SIZE_OF_INT,reg,cext_at(0,0)); | 6034 code_ld(cload(0,0),regv_l(reg),SIZE_OF_INT,adr,cext_at(0,0)); |
6020 i = 64-(bitsize-(32-bitpos)); | 6035 i = 64-(bitsize-(32-bitpos)); |
6021 loprtc(LLSHIFT,lreg,list2(CONST,i)); | 6036 loprtc(LLSHIFT,reg,list2(CONST,i)); |
6022 if (i<0||64<=i) error(-1); | 6037 if (i<0||64<=i) error(-1); |
6023 /* load lllll */ | 6038 /* load lllll */ |
6024 code_ld(cload(0,0),reg,0,reg,cext_at(0,0)); | 6039 code_ld(cload(0,0),adr,0,adr,cext_at(0,0)); |
6025 i = (bitsize-(32-bitpos))-32; | 6040 i = (bitsize-(32-bitpos))-32; |
6026 oprtc(URSHIFT,reg,list2(CONST,i)); | 6041 oprtc(URSHIFT,adr,list2(CONST,i)); |
6027 if (i<0||32<=i) error(-1); | 6042 if (i<0||32<=i) error(-1); |
6028 inc_inst(1); | 6043 inc_inst(1); |
6029 printf("\tadd\t%s,%s,%s\n", | 6044 printf("\tadd\t%s,%s,%s\n", |
6030 register_name(regv_l(lreg)), | 6045 register_name(regv_l(reg)), |
6031 register_name(regv_l(lreg)), | 6046 register_name(regv_l(reg)), |
6032 register_name(reg)); | 6047 register_name(adr)); |
6033 i = 64-bitsize; | 6048 i = 64-bitsize; |
6034 loprtc(sign?LRSHIFT:LURSHIFT,lreg,list2(CONST,i)); | 6049 loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); |
6035 if (i<0||64<=i) error(-1); | 6050 if (i<0||64<=i) error(-1); |
6036 set_lreg(lreg,1); | 6051 if (adhoc>0) free_register(adhoc); |
6037 } else { | 6052 } else { |
6053 use_int(adr); | |
6038 use_int(reg); | 6054 use_int(reg); |
6055 code_ld(cload(0,0),reg,SIZE_OF_INT,adr,cext_at(0,0)); | |
6039 /* shift left */ | 6056 /* shift left */ |
6040 if ((i=32-bitsize-bitpos)) | 6057 if ((i=32-bitsize-bitpos)) |
6041 oprtc(LSHIFT,reg,list2(CONST,i)); | 6058 oprtc(LSHIFT,reg,list2(CONST,i)); |
6042 /* shift right */ | 6059 /* shift right */ |
6043 if ((i=32-bitsize)) | 6060 if ((i=32-bitsize)) |
6062 /* do disjunction */ | 6079 /* do disjunction */ |
6063 printf("\torr\t%s, %s, %s\n",crn,trn,lrn); | 6080 printf("\torr\t%s, %s, %s\n",crn,trn,lrn); |
6064 } | 6081 } |
6065 | 6082 |
6066 extern void | 6083 extern void |
6067 code_bit_replace(int value,int lvalue,int type,int bitpos) | 6084 code_bit_replace(int adr,int value,int type) |
6068 { | 6085 { |
6069 int sign,bitsz,l,align,i; | 6086 int sign,bitsz,l,align,i; |
6070 int bitsize = caddr(caddr(type)); | 6087 int bitsize,bitpos; |
6071 int mask = 0; | 6088 int mask = 0; |
6072 int tmp = -1; | 6089 int tmp = -1,lvalue,size; |
6073 int tmpvar = -1; | 6090 int tmpvar = -1; |
6074 char *crn,*lrn,*trn; | 6091 char *crn,*lrn,*trn; |
6075 set_bitsz(type,&sign,&bitsz,&align,&l); | 6092 set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); |
6093 size = bitsz/8; | |
6076 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); | 6094 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); |
6077 if (l==1) { | 6095 if (l==1) { |
6096 use_int(adr); | |
6097 lvalue = get_lregister(); | |
6098 lload(adr,lvalue,0); | |
6078 use_longlong(value); | 6099 use_longlong(value); |
6079 crn = lregister_name_high(value); | 6100 crn = lregister_name_high(value); |
6080 lrn = lregister_name_high(lvalue); | 6101 lrn = lregister_name_high(lvalue); |
6081 /* shift left */ | 6102 /* shift left */ |
6082 if (bitpos) | 6103 if (bitpos) |
6092 if (bitpos<32) { | 6113 if (bitpos<32) { |
6093 /* make and-mask lower */ | 6114 /* make and-mask lower */ |
6094 mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); | 6115 mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); |
6095 make_mask_and_or(mask,tmp,trn,crn,lrn); | 6116 make_mask_and_or(mask,tmp,trn,crn,lrn); |
6096 } | 6117 } |
6118 code_lassign(adr,value); | |
6119 free_register(lvalue); | |
6097 } else if (l==2) { | 6120 } else if (l==2) { |
6121 use_int(adr); | |
6098 use_longlong(value); | 6122 use_longlong(value); |
6099 tmpvar=new_lvar(SIZE_OF_LONGLONG); | 6123 tmpvar=new_lvar(SIZE_OF_LONGLONG); |
6100 code_lassign_lvar(tmpvar,value); | 6124 code_lassign_lvar(tmpvar,value); |
6101 use_int(lvalue); | |
6102 trn = register_name(tmp = get_register()); | 6125 trn = register_name(tmp = get_register()); |
6103 | 6126 |
6104 /* make and-mask upper */ | 6127 /* make and-mask upper */ |
6105 i=bitpos; | 6128 i=bitpos; |
6106 if (i) | 6129 if (i) |
6107 oprtc(LSHIFT,regv_l(value),list2(CONST,i)); | 6130 oprtc(LSHIFT,regv_l(value),list2(CONST,i)); |
6108 if (i<0||32<=i) error(-1); | 6131 if (i<0||32<=i) error(-1); |
6109 crn = lregister_name_low(value); | 6132 crn = lregister_name_low(value); |
6110 code_ld(cload(0,0),regv_h(value),0,lvalue,cext_at(0,0)); | 6133 code_ld(cload(0,0),regv_h(value),0,adr,cext_at(0,0)); |
6111 lrn = lregister_name_high(value); | 6134 lrn = lregister_name_high(value); |
6112 mask = make_mask(0,31-bitpos); | 6135 mask = make_mask(0,31-bitpos); |
6113 make_mask_and_or(mask,tmp,trn,crn,lrn); | 6136 make_mask_and_or(mask,tmp,trn,crn,lrn); |
6114 inc_inst(1); | 6137 inc_inst(1); |
6115 printf("\t%s\t%s, [%s, #0]\n",cstore(0),crn,register_name(lvalue)); | 6138 printf("\t%s\t%s, [%s, #0]\n",cstore(0),crn,register_name(adr)); |
6116 /* | 6139 /* |
6117 <-----bitsize---------------> | 6140 <-----bitsize---------------> |
6118 hhhhhh mmmmmmmmmmmm lllllll | 6141 hhhhhh mmmmmmmmmmmm lllllll |
6119 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh | 6142 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh |
6120 |-----||-----------||------------||-------||-------| | 6143 |-----||-----------||------------||-------||-------| |
6127 i=32-bitpos; | 6150 i=32-bitpos; |
6128 if (i) | 6151 if (i) |
6129 loprtc(LRSHIFT,value,list2(CONST,i)); | 6152 loprtc(LRSHIFT,value,list2(CONST,i)); |
6130 if (i<0||64<=i) error(-1); | 6153 if (i<0||64<=i) error(-1); |
6131 inc_inst(1); | 6154 inc_inst(1); |
6132 printf("\t%s\t%s, [%s, #4]\n",cstore(0),crn,register_name(lvalue)); | 6155 printf("\t%s\t%s, [%s, #4]\n",cstore(0),crn,register_name(adr)); |
6133 | 6156 |
6134 /* make and-mask lower */ | 6157 /* make and-mask lower */ |
6135 code_ld(cload(0,0),regv_l(value),SIZE_OF_INT*2,lvalue,cext_at(0,0)); | 6158 code_ld(cload(0,0),regv_l(value),SIZE_OF_INT*2,adr,cext_at(0,0)); |
6136 if (i<0||64<=i) error(-1); | 6159 if (i<0||64<=i) error(-1); |
6137 mask = make_mask(bitsz-bitpos-bitsize,31); | 6160 mask = make_mask(bitsz-bitpos-bitsize,31); |
6138 make_mask_and_or(mask,tmp,trn,lrn,crn); | 6161 make_mask_and_or(mask,tmp,trn,lrn,crn); |
6139 inc_inst(1); | 6162 inc_inst(1); |
6140 printf("\t%s\t%s, [%s, #8]\n",cstore(0),lrn,register_name(lvalue)); | 6163 printf("\t%s\t%s, [%s, #8]\n",cstore(0),lrn,register_name(adr)); |
6141 free_lvar(tmpvar); | 6164 free_lvar(tmpvar); |
6142 set_ireg(lvalue,0); | |
6143 } else { | 6165 } else { |
6166 use_int(adr); | |
6144 use_int(value); | 6167 use_int(value); |
6168 lvalue = get_register(); | |
6169 code_ld(cload(size,sign),lvalue,0,adr,cext_at(0,0)); | |
6145 crn = register_name(value); | 6170 crn = register_name(value); |
6146 lrn = register_name(lvalue); | 6171 lrn = register_name(lvalue); |
6147 /* shift left */ | 6172 /* shift left */ |
6148 if (bitpos) | 6173 if (bitpos) |
6149 oprtc(LSHIFT,value,list2(CONST,bitpos)); | 6174 oprtc(LSHIFT,value,list2(CONST,bitpos)); |
6150 trn = register_name(tmp = get_register()); | 6175 trn = register_name(tmp = get_register()); |
6151 /* make and-mask */ | 6176 /* make and-mask */ |
6152 mask = make_mask(32-bitpos-bitsize,31-bitpos); | 6177 mask = make_mask(32-bitpos-bitsize,31-bitpos); |
6153 make_mask_and_or(mask,tmp,trn,crn,lrn); | 6178 make_mask_and_or(mask,tmp,trn,crn,lrn); |
6179 code_assign(adr,size,value); | |
6180 free_register(lvalue); | |
6154 } | 6181 } |
6155 if (tmp!=-1) free_register(tmp); | 6182 if (tmp!=-1) free_register(tmp); |
6183 if (use) { | |
6184 code_bit_field(type,adr,USE_CREG); | |
6185 } | |
6156 } | 6186 } |
6157 | 6187 |
6158 | 6188 |
6159 static void | 6189 static void |
6160 make_mask_and_or_const(int mask,char *crn,int c) | 6190 make_mask_and_or_const(int mask,char *crn,int c) |
6190 } | 6220 } |
6191 if (tmp!=-1) free_register(tmp); | 6221 if (tmp!=-1) free_register(tmp); |
6192 } | 6222 } |
6193 | 6223 |
6194 extern void | 6224 extern void |
6195 code_bit_replace_const(int value,int lvalue,int type,int bitpos) | 6225 code_bit_replace_const(int value,int adr,int type) |
6196 { | 6226 { |
6197 int sign,bitsz,l,align; | 6227 int sign,bitsz,l,align; |
6198 int bitsize = caddr(caddr(type)); | 6228 int bitsize,bitpos,size; |
6199 int mask = 0; | 6229 int mask = 0; |
6200 int c; | 6230 int c; |
6231 int lvalue; | |
6201 #if LONGLONG_CODE | 6232 #if LONGLONG_CODE |
6202 long long lc; | 6233 long long lc; |
6203 int tmp; | 6234 int tmp; |
6204 #endif | 6235 #endif |
6205 char *crn,*trn; | 6236 char *crn,*trn; |
6206 set_bitsz(type,&sign,&bitsz,&align,&l); | 6237 set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); |
6238 size = bitsz/8; | |
6207 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); | 6239 // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); |
6208 if (l==1) { | 6240 if (l==1) { |
6209 #if LONGLONG_CODE | 6241 #if LONGLONG_CODE |
6210 use_longlong(lvalue); | 6242 use_int(adr); |
6243 lvalue = get_lregister(); | |
6244 lload(adr,lvalue,0); | |
6211 crn = lregister_name_high(lvalue); | 6245 crn = lregister_name_high(lvalue); |
6212 /* shift left */ | 6246 /* shift left */ |
6213 lc = lcadr(value); | 6247 lc = lcadr(value); |
6214 lc <<= bitpos; | 6248 lc <<= bitpos; |
6215 if (bitpos+bitsize>=32) { | 6249 if (bitpos+bitsize>=32) { |
6221 if (bitpos<32) { | 6255 if (bitpos<32) { |
6222 /* make and-mask lower */ | 6256 /* make and-mask lower */ |
6223 mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); | 6257 mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); |
6224 make_mask_and_or_const(mask,crn,(int)lc); | 6258 make_mask_and_or_const(mask,crn,(int)lc); |
6225 } | 6259 } |
6260 free_register(lvalue); | |
6226 } else if (l==2) { | 6261 } else if (l==2) { |
6227 /* | 6262 /* |
6228 hhhhhh mmmmmmmmmmmm lllllll | 6263 hhhhhh mmmmmmmmmmmm lllllll |
6229 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh | 6264 lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh |
6230 |-----||-----------||------------||-------||-------| | 6265 |-----||-----------||------------||-------||-------| |
6231 */ | 6266 */ |
6232 use_int(lvalue); | 6267 use_int(adr); |
6233 crn = register_name(lvalue); | 6268 crn = register_name(adr); |
6234 trn = register_name(tmp = get_register()); | 6269 trn = register_name(tmp = get_register()); |
6235 /* shift right */ | 6270 /* shift right */ |
6236 lc = lcadr(value); | 6271 lc = lcadr(value); |
6237 /* make and-mask upper */ | 6272 /* make and-mask upper */ |
6238 code_ld(cload(0,0),tmp,0,lvalue,cext_at(0,0)); | 6273 code_ld(cload(0,0),tmp,0,adr,cext_at(0,0)); |
6239 mask = make_mask(0,31-bitpos); | 6274 mask = make_mask(0,31-bitpos); |
6240 make_mask_and_or_const(mask,trn,(int)(lc<<bitpos)); | 6275 make_mask_and_or_const(mask,trn,(int)(lc<<bitpos)); |
6241 inc_inst(1); | 6276 inc_inst(1); |
6242 printf("\t%s\t%s, [%s, #0]\n",cstore(0),trn,crn); | 6277 printf("\t%s\t%s, [%s, #0]\n",cstore(0),trn,crn); |
6243 /* store middle */ | 6278 /* store middle */ |
6244 code_const((int)(lc>>(32-bitpos)),tmp); | 6279 code_const((int)(lc>>(32-bitpos)),tmp); |
6245 inc_inst(1); | 6280 inc_inst(1); |
6246 printf("\t%s\t%s, [%s, #4]\n",cstore(0),trn,crn); | 6281 printf("\t%s\t%s, [%s, #4]\n",cstore(0),trn,crn); |
6247 /* make and-mask lower */ | 6282 /* make and-mask lower */ |
6248 code_ld(cload(0,0),tmp,SIZE_OF_INT*2,lvalue,cext_at(0,0)); | 6283 code_ld(cload(0,0),tmp,SIZE_OF_INT*2,adr,cext_at(0,0)); |
6249 mask = make_mask(bitsz-bitpos-bitsize,31); | 6284 mask = make_mask(bitsz-bitpos-bitsize,31); |
6250 make_mask_and_or_const(mask,trn,(int)(lc>>(64-bitpos))); | 6285 make_mask_and_or_const(mask,trn,(int)(lc>>(64-bitpos))); |
6251 inc_inst(1); | 6286 inc_inst(1); |
6252 printf("\t%s\t%s, [%s, #8]\n",cstore(0),trn,crn); | 6287 printf("\t%s\t%s, [%s, #8]\n",cstore(0),trn,crn); |
6288 free_register(tmp); | |
6253 #endif | 6289 #endif |
6254 } else { | 6290 } else { |
6255 use_int(lvalue); | 6291 use_int(adr); |
6292 lvalue = get_register(); | |
6293 code_ld(cload(size,sign),lvalue,SIZE_OF_INT*2,adr,cext_at(0,0)); | |
6256 crn = register_name(lvalue); | 6294 crn = register_name(lvalue); |
6257 /* shift left */ | 6295 /* shift left */ |
6258 c = cadr(value); | 6296 c = cadr(value); |
6259 c <<= bitpos; | 6297 c <<= bitpos; |
6260 /* make and-mask */ | 6298 /* make and-mask */ |
6261 mask = make_mask(32-bitpos-bitsize,31-bitpos); | 6299 mask = make_mask(32-bitpos-bitsize,31-bitpos); |
6262 make_mask_and_or_const(mask,crn,c); | 6300 make_mask_and_or_const(mask,crn,c); |
6301 code_assign(adr,size,lvalue); | |
6302 free_register(lvalue); | |
6303 } | |
6304 if (use) { | |
6305 code_bit_field(type,adr,USE_CREG); | |
6263 } | 6306 } |
6264 } | 6307 } |
6265 | 6308 |
6266 | 6309 |
6267 #endif | 6310 #endif |