Revision 24e838b7
b/tcg/arm/tcg-target.c | ||
---|---|---|
375 | 375 |
tcg_out32(s, (cond << 28) | 0x012fff30 | rn); |
376 | 376 |
} |
377 | 377 |
|
378 |
static inline void tcg_out_blx_imm(TCGContext *s, int32_t offset) |
|
379 |
{ |
|
380 |
tcg_out32(s, 0xfa000000 | ((offset & 2) << 23) | |
|
381 |
(((offset - 8) >> 2) & 0x00ffffff)); |
|
382 |
} |
|
383 |
|
|
378 | 384 |
static inline void tcg_out_dat_reg(TCGContext *s, |
379 | 385 |
int cond, int opc, int rd, int rn, int rm, int shift) |
380 | 386 |
{ |
... | ... | |
840 | 846 |
{ |
841 | 847 |
int32_t val; |
842 | 848 |
|
849 |
if (addr & 1) { |
|
850 |
/* goto to a Thumb destination isn't supported */ |
|
851 |
tcg_abort(); |
|
852 |
} |
|
853 |
|
|
843 | 854 |
val = addr - (tcg_target_long) s->code_ptr; |
844 | 855 |
if (val - 8 < 0x01fffffd && val - 8 > -0x01fffffd) |
845 | 856 |
tcg_out_b(s, cond, val); |
... | ... | |
860 | 871 |
} |
861 | 872 |
} |
862 | 873 |
|
863 |
static inline void tcg_out_call(TCGContext *s, int cond, uint32_t addr)
|
|
874 |
static inline void tcg_out_call(TCGContext *s, uint32_t addr) |
|
864 | 875 |
{ |
865 | 876 |
int32_t val; |
866 | 877 |
|
867 | 878 |
val = addr - (tcg_target_long) s->code_ptr; |
868 |
if (val < 0x01fffffd && val > -0x01fffffd) |
|
869 |
tcg_out_bl(s, cond, val); |
|
870 |
else { |
|
879 |
if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) { |
|
880 |
if (addr & 1) { |
|
881 |
/* Use BLX if the target is in Thumb mode */ |
|
882 |
if (!use_armv5_instructions) { |
|
883 |
tcg_abort(); |
|
884 |
} |
|
885 |
tcg_out_blx_imm(s, val); |
|
886 |
} else { |
|
887 |
tcg_out_bl(s, COND_AL, val); |
|
888 |
} |
|
889 |
} else { |
|
871 | 890 |
#if 1 |
872 | 891 |
tcg_abort(); |
873 | 892 |
#else |
... | ... | |
1063 | 1082 |
TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0)); |
1064 | 1083 |
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index); |
1065 | 1084 |
# endif |
1066 |
tcg_out_bl(s, COND_AL, (tcg_target_long) qemu_ld_helpers[s_bits] - |
|
1067 |
(tcg_target_long) s->code_ptr); |
|
1085 |
tcg_out_call(s, (tcg_target_long) qemu_ld_helpers[s_bits]); |
|
1068 | 1086 |
|
1069 | 1087 |
switch (opc) { |
1070 | 1088 |
case 0 | 4: |
... | ... | |
1330 | 1348 |
} |
1331 | 1349 |
# endif |
1332 | 1350 |
|
1333 |
tcg_out_bl(s, COND_AL, (tcg_target_long) qemu_st_helpers[s_bits] - |
|
1334 |
(tcg_target_long) s->code_ptr); |
|
1351 |
tcg_out_call(s, (tcg_target_long) qemu_st_helpers[s_bits]); |
|
1335 | 1352 |
if (opc == 3) |
1336 | 1353 |
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10); |
1337 | 1354 |
|
... | ... | |
1443 | 1460 |
break; |
1444 | 1461 |
case INDEX_op_call: |
1445 | 1462 |
if (const_args[0]) |
1446 |
tcg_out_call(s, COND_AL, args[0]);
|
|
1463 |
tcg_out_call(s, args[0]); |
|
1447 | 1464 |
else |
1448 | 1465 |
tcg_out_callr(s, COND_AL, args[0]); |
1449 | 1466 |
break; |
Also available in: Unified diff