Revision 94953e6d
b/tcg/arm/tcg-target.c | ||
---|---|---|
179 | 179 |
return 0; |
180 | 180 |
} |
181 | 181 |
|
182 |
static inline uint32_t rotl(uint32_t val, int n) |
|
183 |
{ |
|
184 |
return (val << n) | (val >> (32 - n)); |
|
185 |
} |
|
186 |
|
|
187 |
/* ARM immediates for ALU instructions are made of an unsigned 8-bit |
|
188 |
right-rotated by an even amount between 0 and 30. */ |
|
189 |
static inline int encode_imm(uint32_t imm) |
|
190 |
{ |
|
191 |
/* simple case, only lower bits */ |
|
192 |
if ((imm & ~0xff) == 0) |
|
193 |
return 0; |
|
194 |
/* then try a simple even shift */ |
|
195 |
shift = ctz32(imm) & ~1; |
|
196 |
if (((imm >> shift) & ~0xff) == 0) |
|
197 |
return 32 - shift; |
|
198 |
/* now try harder with rotations */ |
|
199 |
if ((rotl(imm, 2) & ~0xff) == 0) |
|
200 |
return 2; |
|
201 |
if ((rotl(imm, 4) & ~0xff) == 0) |
|
202 |
return 4; |
|
203 |
if ((rotl(imm, 6) & ~0xff) == 0) |
|
204 |
return 6; |
|
205 |
/* imm can't be encoded */ |
|
206 |
return -1; |
|
207 |
} |
|
182 | 208 |
|
183 | 209 |
static inline int check_fit_imm(uint32_t imm) |
184 | 210 |
{ |
185 |
/* XXX: use rotation */ |
|
186 |
return (imm & ~0xff) == 0; |
|
211 |
return encode_imm(imm) >= 0; |
|
187 | 212 |
} |
188 | 213 |
|
189 | 214 |
/* Test if a constant matches the constraint. |
... | ... | |
1407 | 1432 |
c = ARITH_EOR; |
1408 | 1433 |
/* Fall through. */ |
1409 | 1434 |
gen_arith: |
1410 |
if (const_args[2]) |
|
1435 |
if (const_args[2]) { |
|
1436 |
int rot; |
|
1437 |
rot = encode_imm(args[2]); |
|
1411 | 1438 |
tcg_out_dat_imm(s, COND_AL, c, |
1412 |
args[0], args[1], args[2]);
|
|
1413 |
else |
|
1439 |
args[0], args[1], rotl(args[2], rot) | (rot << 7));
|
|
1440 |
} else
|
|
1414 | 1441 |
tcg_out_dat_reg(s, COND_AL, c, |
1415 | 1442 |
args[0], args[1], args[2], SHIFT_IMM_LSL(0)); |
1416 | 1443 |
break; |
Also available in: Unified diff