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