Merge remote-tracking branch 'rth/tcg-next' into staging

# By Richard Henderson
# Via Richard Henderson
* rth/tcg-next:
  tcg-arm: Implement tcg_register_jit
  tcg-i386: Use QEMU_BUILD_BUG_ON instead of assert for frame size
  tcg: Move the CIE and FDE header definitions to common code
  tcg: Fix high_pc fields in .debug_info
  tcg-arm: Use AT_PLATFORM to detect the host ISA
  tcg-arm: Simplify logic in detecting the ARM ISA in use
  tcg-arm: Rename use_armv5_instructions to use_armvt5_instructions
  tcg-arm: Make use of conditional availability of opcodes for divide
  tcg: Simplify logic using TCG_OPF_NOT_PRESENT
  tcg: Allow non-constant control macros
  tcg-ppc64: Don't implement rem
  tcg-ppc: Don't implement rem
  tcg-arm: Don't implement rem
  tcg: Split rem requirement from div requirement
  tcg: Add myself to general TCG maintainership

Message-id: 1373379515-28596-1-git-send-email-rth@twiddle.net
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Anthony Liguori 2013-07-10 10:53:55 -05:00
commit 6272d17c42
20 changed files with 248 additions and 218 deletions

View File

@ -781,6 +781,7 @@ Tiny Code Generator (TCG)
------------------------- -------------------------
Common code Common code
M: qemu-devel@nongnu.org M: qemu-devel@nongnu.org
M: Richard Henderson <rth@twiddle.net>
S: Maintained S: Maintained
F: tcg/ F: tcg/

View File

@ -40,6 +40,7 @@ typedef enum {
/* optional instructions */ /* optional instructions */
#define TCG_TARGET_HAS_div_i32 0 #define TCG_TARGET_HAS_div_i32 0
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_ext8s_i32 1 #define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1 #define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1 #define TCG_TARGET_HAS_ext8u_i32 1
@ -62,6 +63,7 @@ typedef enum {
#define TCG_TARGET_HAS_muls2_i32 0 #define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_div_i64 0 #define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_ext8s_i64 1 #define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1 #define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1 #define TCG_TARGET_HAS_ext32s_i64 1

View File

@ -22,50 +22,43 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#if defined(__ARM_ARCH_7__) || \ /* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */
defined(__ARM_ARCH_7A__) || \ #ifndef __ARM_ARCH
defined(__ARM_ARCH_7EM__) || \ # if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
defined(__ARM_ARCH_7M__) || \ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7EM__)
#define USE_ARMV7_INSTRUCTIONS # define __ARM_ARCH 7
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|| defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
# define __ARM_ARCH 6
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) \
|| defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
|| defined(__ARM_ARCH_5TEJ__)
# define __ARM_ARCH 5
# else
# define __ARM_ARCH 4
# endif
#endif #endif
#if defined(USE_ARMV7_INSTRUCTIONS) || \ static int arm_arch = __ARM_ARCH;
defined(__ARM_ARCH_6J__) || \
defined(__ARM_ARCH_6K__) || \
defined(__ARM_ARCH_6T2__) || \
defined(__ARM_ARCH_6Z__) || \
defined(__ARM_ARCH_6ZK__)
#define USE_ARMV6_INSTRUCTIONS
#endif
#if defined(USE_ARMV6_INSTRUCTIONS) || \ #if defined(__ARM_ARCH_5T__) \
defined(__ARM_ARCH_5T__) || \ || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
defined(__ARM_ARCH_5TE__) || \ # define use_armv5t_instructions 1
defined(__ARM_ARCH_5TEJ__)
#define USE_ARMV5_INSTRUCTIONS
#endif
#ifdef USE_ARMV5_INSTRUCTIONS
static const int use_armv5_instructions = 1;
#else #else
static const int use_armv5_instructions = 0; # define use_armv5t_instructions use_armv6_instructions
#endif #endif
#undef USE_ARMV5_INSTRUCTIONS
#ifdef USE_ARMV6_INSTRUCTIONS #define use_armv6_instructions (__ARM_ARCH >= 6 || arm_arch >= 6)
static const int use_armv6_instructions = 1; #define use_armv7_instructions (__ARM_ARCH >= 7 || arm_arch >= 7)
#else
static const int use_armv6_instructions = 0;
#endif
#undef USE_ARMV6_INSTRUCTIONS
#ifdef USE_ARMV7_INSTRUCTIONS #ifndef use_idiv_instructions
static const int use_armv7_instructions = 1; bool use_idiv_instructions;
#else #endif
static const int use_armv7_instructions = 0; #ifdef CONFIG_GETAUXVAL
# include <sys/auxv.h>
#endif #endif
#undef USE_ARMV7_INSTRUCTIONS
#ifndef NDEBUG #ifndef NDEBUG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
@ -1023,7 +1016,7 @@ static inline void tcg_out_call(TCGContext *s, uint32_t addr)
if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) { if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) {
if (addr & 1) { if (addr & 1) {
/* Use BLX if the target is in Thumb mode */ /* Use BLX if the target is in Thumb mode */
if (!use_armv5_instructions) { if (!use_armv5t_instructions) {
tcg_abort(); tcg_abort();
} }
tcg_out_blx_imm(s, val); tcg_out_blx_imm(s, val);
@ -1042,7 +1035,7 @@ static inline void tcg_out_call(TCGContext *s, uint32_t addr)
static inline void tcg_out_callr(TCGContext *s, int cond, int arg) static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
{ {
if (use_armv5_instructions) { if (use_armv5t_instructions) {
tcg_out_blx(s, cond, arg); tcg_out_blx(s, cond, arg);
} else { } else {
tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0, tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
@ -1926,18 +1919,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_divu_i32: case INDEX_op_divu_i32:
tcg_out_udiv(s, COND_AL, args[0], args[1], args[2]); tcg_out_udiv(s, COND_AL, args[0], args[1], args[2]);
break; break;
case INDEX_op_rem_i32:
tcg_out_sdiv(s, COND_AL, TCG_REG_TMP, args[1], args[2]);
tcg_out_mul32(s, COND_AL, TCG_REG_TMP, TCG_REG_TMP, args[2]);
tcg_out_dat_reg(s, COND_AL, ARITH_SUB, args[0], args[1], TCG_REG_TMP,
SHIFT_IMM_LSL(0));
break;
case INDEX_op_remu_i32:
tcg_out_udiv(s, COND_AL, TCG_REG_TMP, args[1], args[2]);
tcg_out_mul32(s, COND_AL, TCG_REG_TMP, TCG_REG_TMP, args[2]);
tcg_out_dat_reg(s, COND_AL, ARITH_SUB, args[0], args[1], TCG_REG_TMP,
SHIFT_IMM_LSL(0));
break;
default: default:
tcg_abort(); tcg_abort();
@ -2041,18 +2022,31 @@ static const TCGTargetOpDef arm_op_defs[] = {
{ INDEX_op_deposit_i32, { "r", "0", "rZ" } }, { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
#if TCG_TARGET_HAS_div_i32
{ INDEX_op_div_i32, { "r", "r", "r" } }, { INDEX_op_div_i32, { "r", "r", "r" } },
{ INDEX_op_rem_i32, { "r", "r", "r" } },
{ INDEX_op_divu_i32, { "r", "r", "r" } }, { INDEX_op_divu_i32, { "r", "r", "r" } },
{ INDEX_op_remu_i32, { "r", "r", "r" } },
#endif
{ -1 }, { -1 },
}; };
static void tcg_target_init(TCGContext *s) static void tcg_target_init(TCGContext *s)
{ {
#if defined(CONFIG_GETAUXVAL)
/* Only probe for the platform and capabilities if we havn't already
determined maximum values at compile time. */
# if !defined(use_idiv_instructions)
{
unsigned long hwcap = getauxval(AT_HWCAP);
use_idiv_instructions = (hwcap & HWCAP_ARM_IDIVA) != 0;
}
# endif
if (__ARM_ARCH < 7) {
const char *pl = (const char *)getauxval(AT_PLATFORM);
if (pl != NULL && pl[0] == 'v' && pl[1] >= '4' && pl[1] <= '9') {
arm_arch = pl[1] - '0';
}
}
#endif /* GETAUXVAL */
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff); tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
tcg_regset_set32(tcg_target_call_clobber_regs, 0, tcg_regset_set32(tcg_target_call_clobber_regs, 0,
(1 << TCG_REG_R0) | (1 << TCG_REG_R0) |
@ -2094,23 +2088,31 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
tcg_out_movi32(s, COND_AL, ret, arg); tcg_out_movi32(s, COND_AL, ret, arg);
} }
/* Compute frame size via macros, to share between tcg_target_qemu_prologue
and tcg_register_jit. */
#define PUSH_SIZE ((11 - 4 + 1 + 1) * sizeof(tcg_target_long))
#define FRAME_SIZE \
((PUSH_SIZE \
+ TCG_STATIC_CALL_ARGS_SIZE \
+ CPU_TEMP_BUF_NLONGS * sizeof(long) \
+ TCG_TARGET_STACK_ALIGN - 1) \
& -TCG_TARGET_STACK_ALIGN)
static void tcg_target_qemu_prologue(TCGContext *s) static void tcg_target_qemu_prologue(TCGContext *s)
{ {
int frame_size; int stack_addend;
/* Calling convention requires us to save r4-r11 and lr. */ /* Calling convention requires us to save r4-r11 and lr. */
/* stmdb sp!, { r4 - r11, lr } */ /* stmdb sp!, { r4 - r11, lr } */
tcg_out32(s, (COND_AL << 28) | 0x092d4ff0); tcg_out32(s, (COND_AL << 28) | 0x092d4ff0);
/* Allocate the local stack frame. */ /* Reserve callee argument and tcg temp space. */
frame_size = TCG_STATIC_CALL_ARGS_SIZE; stack_addend = FRAME_SIZE - PUSH_SIZE;
frame_size += CPU_TEMP_BUF_NLONGS * sizeof(long);
/* We saved an odd number of registers above; keep an 8 aligned stack. */
frame_size = ((frame_size + TCG_TARGET_STACK_ALIGN - 1)
& -TCG_TARGET_STACK_ALIGN) + 4;
tcg_out_dat_rI(s, COND_AL, ARITH_SUB, TCG_REG_CALL_STACK, tcg_out_dat_rI(s, COND_AL, ARITH_SUB, TCG_REG_CALL_STACK,
TCG_REG_CALL_STACK, frame_size, 1); TCG_REG_CALL_STACK, stack_addend, 1);
tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE, tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
CPU_TEMP_BUF_NLONGS * sizeof(long)); CPU_TEMP_BUF_NLONGS * sizeof(long));
@ -2121,8 +2123,58 @@ static void tcg_target_qemu_prologue(TCGContext *s)
/* Epilogue. We branch here via tb_ret_addr. */ /* Epilogue. We branch here via tb_ret_addr. */
tcg_out_dat_rI(s, COND_AL, ARITH_ADD, TCG_REG_CALL_STACK, tcg_out_dat_rI(s, COND_AL, ARITH_ADD, TCG_REG_CALL_STACK,
TCG_REG_CALL_STACK, frame_size, 1); TCG_REG_CALL_STACK, stack_addend, 1);
/* ldmia sp!, { r4 - r11, pc } */ /* ldmia sp!, { r4 - r11, pc } */
tcg_out32(s, (COND_AL << 28) | 0x08bd8ff0); tcg_out32(s, (COND_AL << 28) | 0x08bd8ff0);
} }
typedef struct {
DebugFrameCIE cie;
DebugFrameFDEHeader fde;
uint8_t fde_def_cfa[4];
uint8_t fde_reg_ofs[18];
} DebugFrame;
#define ELF_HOST_MACHINE EM_ARM
/* We're expecting a 2 byte uleb128 encoded value. */
QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
static DebugFrame debug_frame = {
.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
.cie.id = -1,
.cie.version = 1,
.cie.code_align = 1,
.cie.data_align = 0x7c, /* sleb128 -4 */
.cie.return_column = 14,
/* Total FDE size does not include the "len" member. */
.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
.fde_def_cfa = {
12, 13, /* DW_CFA_def_cfa sp, ... */
(FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
(FRAME_SIZE >> 7)
},
.fde_reg_ofs = {
/* The following must match the stmdb in the prologue. */
0x8e, 1, /* DW_CFA_offset, lr, -4 */
0x8b, 2, /* DW_CFA_offset, r11, -8 */
0x8a, 3, /* DW_CFA_offset, r10, -12 */
0x89, 4, /* DW_CFA_offset, r9, -16 */
0x88, 5, /* DW_CFA_offset, r8, -20 */
0x87, 6, /* DW_CFA_offset, r7, -24 */
0x86, 7, /* DW_CFA_offset, r6, -28 */
0x85, 8, /* DW_CFA_offset, r5, -32 */
0x84, 9, /* DW_CFA_offset, r4, -36 */
}
};
void tcg_register_jit(void *buf, size_t buf_size)
{
debug_frame.fde.func_start = (tcg_target_long) buf;
debug_frame.fde.func_len = buf_size;
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
}

View File

@ -49,6 +49,13 @@ typedef enum {
#define TCG_TARGET_NB_REGS 16 #define TCG_TARGET_NB_REGS 16
#ifdef __ARM_ARCH_EXT_IDIV__
#define use_idiv_instructions 1
#else
extern bool use_idiv_instructions;
#endif
/* used for function call generation */ /* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_R13 #define TCG_REG_CALL_STACK TCG_REG_R13
#define TCG_TARGET_STACK_ALIGN 8 #define TCG_TARGET_STACK_ALIGN 8
@ -73,12 +80,8 @@ typedef enum {
#define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_movcond_i32 1 #define TCG_TARGET_HAS_movcond_i32 1
#define TCG_TARGET_HAS_muls2_i32 1 #define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_div_i32 use_idiv_instructions
#ifdef __ARM_ARCH_EXT_IDIV__ #define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_div_i32 1
#else
#define TCG_TARGET_HAS_div_i32 0
#endif
extern bool tcg_target_deposit_valid(int ofs, int len); extern bool tcg_target_deposit_valid(int ofs, int len);
#define TCG_TARGET_deposit_i32_valid tcg_target_deposit_valid #define TCG_TARGET_deposit_i32_valid tcg_target_deposit_valid

View File

@ -1765,29 +1765,12 @@ static void tcg_target_init(TCGContext *s)
tcg_add_target_add_op_defs(hppa_op_defs); tcg_add_target_add_op_defs(hppa_op_defs);
} }
typedef struct {
uint32_t len __attribute__((aligned((sizeof(void *)))));
uint32_t id;
uint8_t version;
char augmentation[1];
uint8_t code_align;
uint8_t data_align;
uint8_t return_column;
} DebugFrameCIE;
typedef struct {
uint32_t len __attribute__((aligned((sizeof(void *)))));
uint32_t cie_offset;
tcg_target_long func_start __attribute__((packed));
tcg_target_long func_len __attribute__((packed));
uint8_t def_cfa[4];
uint8_t ret_ofs[3];
uint8_t reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
} DebugFrameFDE;
typedef struct { typedef struct {
DebugFrameCIE cie; DebugFrameCIE cie;
DebugFrameFDE fde; DebugFrameFDEHeader fde;
uint8_t fde_def_cfa[4];
uint8_t fde_ret_ofs[3];
uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
} DebugFrame; } DebugFrame;
#define ELF_HOST_MACHINE EM_PARISC #define ELF_HOST_MACHINE EM_PARISC
@ -1806,16 +1789,18 @@ static DebugFrame debug_frame = {
.cie.data_align = 1, .cie.data_align = 1,
.cie.return_column = 2, .cie.return_column = 2,
.fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */ /* Total FDE size does not include the "len" member. */
.fde.def_cfa = { .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
.fde_def_cfa = {
0x12, 30, /* DW_CFA_def_cfa_sf sp, ... */ 0x12, 30, /* DW_CFA_def_cfa_sf sp, ... */
(-FRAME_SIZE & 0x7f) | 0x80, /* ... sleb128 -FRAME_SIZE */ (-FRAME_SIZE & 0x7f) | 0x80, /* ... sleb128 -FRAME_SIZE */
(-FRAME_SIZE >> 7) & 0x7f (-FRAME_SIZE >> 7) & 0x7f
}, },
.fde.ret_ofs = { .fde_ret_ofs = {
0x11, 2, (-20 / 4) & 0x7f /* DW_CFA_offset_extended_sf r2, 20 */ 0x11, 2, (-20 / 4) & 0x7f /* DW_CFA_offset_extended_sf r2, 20 */
}, },
.fde.reg_ofs = { .fde_reg_ofs = {
/* This must match the ordering in tcg_target_callee_save_regs. */ /* This must match the ordering in tcg_target_callee_save_regs. */
0x80 + 4, 0, /* DW_CFA_offset r4, 0 */ 0x80 + 4, 0, /* DW_CFA_offset r4, 0 */
0x80 + 5, 4, /* DW_CFA_offset r5, 4 */ 0x80 + 5, 4, /* DW_CFA_offset r5, 4 */

View File

@ -85,6 +85,7 @@ typedef enum {
/* optional instructions */ /* optional instructions */
#define TCG_TARGET_HAS_div_i32 0 #define TCG_TARGET_HAS_div_i32 0
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_rot_i32 1 #define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1 #define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1 #define TCG_TARGET_HAS_ext16s_i32 1

View File

@ -2311,30 +2311,16 @@ static void tcg_target_init(TCGContext *s)
tcg_add_target_add_op_defs(x86_op_defs); tcg_add_target_add_op_defs(x86_op_defs);
} }
typedef struct {
uint32_t len __attribute__((aligned((sizeof(void *)))));
uint32_t id;
uint8_t version;
char augmentation[1];
uint8_t code_align;
uint8_t data_align;
uint8_t return_column;
} DebugFrameCIE;
typedef struct {
uint32_t len __attribute__((aligned((sizeof(void *)))));
uint32_t cie_offset;
tcg_target_long func_start __attribute__((packed));
tcg_target_long func_len __attribute__((packed));
uint8_t def_cfa[4];
uint8_t reg_ofs[14];
} DebugFrameFDE;
typedef struct { typedef struct {
DebugFrameCIE cie; DebugFrameCIE cie;
DebugFrameFDE fde; DebugFrameFDEHeader fde;
uint8_t fde_def_cfa[4];
uint8_t fde_reg_ofs[14];
} DebugFrame; } DebugFrame;
/* We're expecting a 2 byte uleb128 encoded value. */
QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
#if !defined(__ELF__) #if !defined(__ELF__)
/* Host machine without ELF. */ /* Host machine without ELF. */
#elif TCG_TARGET_REG_BITS == 64 #elif TCG_TARGET_REG_BITS == 64
@ -2347,13 +2333,15 @@ static DebugFrame debug_frame = {
.cie.data_align = 0x78, /* sleb128 -8 */ .cie.data_align = 0x78, /* sleb128 -8 */
.cie.return_column = 16, .cie.return_column = 16,
.fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */ /* Total FDE size does not include the "len" member. */
.fde.def_cfa = { .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
.fde_def_cfa = {
12, 7, /* DW_CFA_def_cfa %rsp, ... */ 12, 7, /* DW_CFA_def_cfa %rsp, ... */
(FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
(FRAME_SIZE >> 7) (FRAME_SIZE >> 7)
}, },
.fde.reg_ofs = { .fde_reg_ofs = {
0x90, 1, /* DW_CFA_offset, %rip, -8 */ 0x90, 1, /* DW_CFA_offset, %rip, -8 */
/* The following ordering must match tcg_target_callee_save_regs. */ /* The following ordering must match tcg_target_callee_save_regs. */
0x86, 2, /* DW_CFA_offset, %rbp, -16 */ 0x86, 2, /* DW_CFA_offset, %rbp, -16 */
@ -2374,13 +2362,15 @@ static DebugFrame debug_frame = {
.cie.data_align = 0x7c, /* sleb128 -4 */ .cie.data_align = 0x7c, /* sleb128 -4 */
.cie.return_column = 8, .cie.return_column = 8,
.fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */ /* Total FDE size does not include the "len" member. */
.fde.def_cfa = { .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
.fde_def_cfa = {
12, 4, /* DW_CFA_def_cfa %esp, ... */ 12, 4, /* DW_CFA_def_cfa %esp, ... */
(FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
(FRAME_SIZE >> 7) (FRAME_SIZE >> 7)
}, },
.fde.reg_ofs = { .fde_reg_ofs = {
0x88, 1, /* DW_CFA_offset, %eip, -4 */ 0x88, 1, /* DW_CFA_offset, %eip, -4 */
/* The following ordering must match tcg_target_callee_save_regs. */ /* The following ordering must match tcg_target_callee_save_regs. */
0x85, 2, /* DW_CFA_offset, %ebp, -8 */ 0x85, 2, /* DW_CFA_offset, %ebp, -8 */
@ -2394,9 +2384,6 @@ static DebugFrame debug_frame = {
#if defined(ELF_HOST_MACHINE) #if defined(ELF_HOST_MACHINE)
void tcg_register_jit(void *buf, size_t buf_size) void tcg_register_jit(void *buf, size_t buf_size)
{ {
/* We're expecting a 2 byte uleb128 encoded value. */
assert(FRAME_SIZE >> 14 == 0);
debug_frame.fde.func_start = (tcg_target_long) buf; debug_frame.fde.func_start = (tcg_target_long) buf;
debug_frame.fde.func_len = buf_size; debug_frame.fde.func_len = buf_size;

View File

@ -104,7 +104,9 @@ typedef enum {
/* optional instructions */ /* optional instructions */
#define TCG_TARGET_HAS_div_i32 0 #define TCG_TARGET_HAS_div_i32 0
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_div_i64 0 #define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_andc_i32 1 #define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_andc_i64 1 #define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_bswap16_i32 1 #define TCG_TARGET_HAS_bswap16_i32 1

View File

@ -79,6 +79,7 @@ typedef enum {
/* optional instructions */ /* optional instructions */
#define TCG_TARGET_HAS_div_i32 1 #define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_not_i32 1 #define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_nor_i32 1 #define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1 #define TCG_TARGET_HAS_ext8s_i32 1

View File

@ -1671,18 +1671,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2])); tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
break; break;
case INDEX_op_rem_i32:
tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
break;
case INDEX_op_remu_i32:
tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
break;
case INDEX_op_mulu2_i32: case INDEX_op_mulu2_i32:
if (args[0] == args[2] || args[0] == args[3]) { if (args[0] == args[2] || args[0] == args[3]) {
tcg_out32 (s, MULLW | TAB (0, args[2], args[3])); tcg_out32 (s, MULLW | TAB (0, args[2], args[3]));
@ -1992,8 +1980,6 @@ static const TCGTargetOpDef ppc_op_defs[] = {
{ INDEX_op_mul_i32, { "r", "r", "ri" } }, { INDEX_op_mul_i32, { "r", "r", "ri" } },
{ INDEX_op_div_i32, { "r", "r", "r" } }, { INDEX_op_div_i32, { "r", "r", "r" } },
{ INDEX_op_divu_i32, { "r", "r", "r" } }, { INDEX_op_divu_i32, { "r", "r", "r" } },
{ INDEX_op_rem_i32, { "r", "r", "r" } },
{ INDEX_op_remu_i32, { "r", "r", "r" } },
{ INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
{ INDEX_op_sub_i32, { "r", "r", "ri" } }, { INDEX_op_sub_i32, { "r", "r", "ri" } },
{ INDEX_op_and_i32, { "r", "r", "ri" } }, { INDEX_op_and_i32, { "r", "r", "ri" } },

View File

@ -78,6 +78,7 @@ typedef enum {
/* optional instructions */ /* optional instructions */
#define TCG_TARGET_HAS_div_i32 1 #define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_rot_i32 1 #define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1 #define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1 #define TCG_TARGET_HAS_ext16s_i32 1

View File

@ -1617,18 +1617,6 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2])); tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
break; break;
case INDEX_op_rem_i32:
tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
break;
case INDEX_op_remu_i32:
tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
break;
case INDEX_op_shl_i32: case INDEX_op_shl_i32:
if (const_args[2]) { if (const_args[2]) {
tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31 - args[2]); tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31 - args[2]);
@ -1786,16 +1774,6 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
case INDEX_op_divu_i64: case INDEX_op_divu_i64:
tcg_out32 (s, DIVDU | TAB (args[0], args[1], args[2])); tcg_out32 (s, DIVDU | TAB (args[0], args[1], args[2]));
break; break;
case INDEX_op_rem_i64:
tcg_out32 (s, DIVD | TAB (0, args[1], args[2]));
tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
break;
case INDEX_op_remu_i64:
tcg_out32 (s, DIVDU | TAB (0, args[1], args[2]));
tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
break;
case INDEX_op_qemu_ld8u: case INDEX_op_qemu_ld8u:
tcg_out_qemu_ld (s, args, 0); tcg_out_qemu_ld (s, args, 0);
@ -2064,8 +2042,6 @@ static const TCGTargetOpDef ppc_op_defs[] = {
{ INDEX_op_mul_i32, { "r", "r", "rI" } }, { INDEX_op_mul_i32, { "r", "r", "rI" } },
{ INDEX_op_div_i32, { "r", "r", "r" } }, { INDEX_op_div_i32, { "r", "r", "r" } },
{ INDEX_op_divu_i32, { "r", "r", "r" } }, { INDEX_op_divu_i32, { "r", "r", "r" } },
{ INDEX_op_rem_i32, { "r", "r", "r" } },
{ INDEX_op_remu_i32, { "r", "r", "r" } },
{ INDEX_op_sub_i32, { "r", "rI", "ri" } }, { INDEX_op_sub_i32, { "r", "rI", "ri" } },
{ INDEX_op_and_i32, { "r", "r", "ri" } }, { INDEX_op_and_i32, { "r", "r", "ri" } },
{ INDEX_op_or_i32, { "r", "r", "ri" } }, { INDEX_op_or_i32, { "r", "r", "ri" } },
@ -2108,8 +2084,6 @@ static const TCGTargetOpDef ppc_op_defs[] = {
{ INDEX_op_mul_i64, { "r", "r", "rI" } }, { INDEX_op_mul_i64, { "r", "r", "rI" } },
{ INDEX_op_div_i64, { "r", "r", "r" } }, { INDEX_op_div_i64, { "r", "r", "r" } },
{ INDEX_op_divu_i64, { "r", "r", "r" } }, { INDEX_op_divu_i64, { "r", "r", "r" } },
{ INDEX_op_rem_i64, { "r", "r", "r" } },
{ INDEX_op_remu_i64, { "r", "r", "r" } },
{ INDEX_op_neg_i64, { "r", "r" } }, { INDEX_op_neg_i64, { "r", "r" } },
{ INDEX_op_not_i64, { "r", "r" } }, { INDEX_op_not_i64, { "r", "r" } },

View File

@ -76,6 +76,7 @@ typedef enum {
/* optional instructions */ /* optional instructions */
#define TCG_TARGET_HAS_div_i32 1 #define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_rot_i32 1 #define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1 #define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1 #define TCG_TARGET_HAS_ext16s_i32 1
@ -96,6 +97,7 @@ typedef enum {
#define TCG_TARGET_HAS_muls2_i32 0 #define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_div_i64 1 #define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_rot_i64 1 #define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1 #define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1 #define TCG_TARGET_HAS_ext16s_i64 1

View File

@ -1646,29 +1646,12 @@ static void tcg_target_init(TCGContext *s)
# define ELF_HOST_FLAGS EF_SPARC_32PLUS # define ELF_HOST_FLAGS EF_SPARC_32PLUS
#endif #endif
typedef struct {
uint32_t len __attribute__((aligned((sizeof(void *)))));
uint32_t id;
uint8_t version;
char augmentation[1];
uint8_t code_align;
uint8_t data_align;
uint8_t return_column;
} DebugFrameCIE;
typedef struct {
uint32_t len __attribute__((aligned((sizeof(void *)))));
uint32_t cie_offset;
tcg_target_long func_start __attribute__((packed));
tcg_target_long func_len __attribute__((packed));
uint8_t def_cfa[TCG_TARGET_REG_BITS == 64 ? 4 : 2];
uint8_t win_save;
uint8_t ret_save[3];
} DebugFrameFDE;
typedef struct { typedef struct {
DebugFrameCIE cie; DebugFrameCIE cie;
DebugFrameFDE fde; DebugFrameFDEHeader fde;
uint8_t fde_def_cfa[TCG_TARGET_REG_BITS == 64 ? 4 : 2];
uint8_t fde_win_save;
uint8_t fde_ret_save[3];
} DebugFrame; } DebugFrame;
static DebugFrame debug_frame = { static DebugFrame debug_frame = {
@ -1679,8 +1662,10 @@ static DebugFrame debug_frame = {
.cie.data_align = -sizeof(void *) & 0x7f, .cie.data_align = -sizeof(void *) & 0x7f,
.cie.return_column = 15, /* o7 */ .cie.return_column = 15, /* o7 */
.fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */ /* Total FDE size does not include the "len" member. */
.fde.def_cfa = { .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
.fde_def_cfa = {
#if TCG_TARGET_REG_BITS == 64 #if TCG_TARGET_REG_BITS == 64
12, 30, /* DW_CFA_def_cfa i6, 2047 */ 12, 30, /* DW_CFA_def_cfa i6, 2047 */
(2047 & 0x7f) | 0x80, (2047 >> 7) (2047 & 0x7f) | 0x80, (2047 >> 7)
@ -1688,8 +1673,8 @@ static DebugFrame debug_frame = {
13, 30 /* DW_CFA_def_cfa_register i6 */ 13, 30 /* DW_CFA_def_cfa_register i6 */
#endif #endif
}, },
.fde.win_save = 0x2d, /* DW_CFA_GNU_window_save */ .fde_win_save = 0x2d, /* DW_CFA_GNU_window_save */
.fde.ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */ .fde_ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
}; };
void tcg_register_jit(void *buf, size_t buf_size) void tcg_register_jit(void *buf, size_t buf_size)

View File

@ -86,6 +86,7 @@ typedef enum {
/* optional instructions */ /* optional instructions */
#define TCG_TARGET_HAS_div_i32 1 #define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_rot_i32 0 #define TCG_TARGET_HAS_rot_i32 0
#define TCG_TARGET_HAS_ext8s_i32 0 #define TCG_TARGET_HAS_ext8s_i32 0
#define TCG_TARGET_HAS_ext16s_i32 0 #define TCG_TARGET_HAS_ext16s_i32 0
@ -109,6 +110,7 @@ typedef enum {
#if TCG_TARGET_REG_BITS == 64 #if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_div_i64 1 #define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_rot_i64 0 #define TCG_TARGET_HAS_rot_i64 0
#define TCG_TARGET_HAS_ext8s_i64 0 #define TCG_TARGET_HAS_ext8s_i64 0
#define TCG_TARGET_HAS_ext16s_i64 0 #define TCG_TARGET_HAS_ext16s_i64 0

View File

@ -731,8 +731,14 @@ static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{ {
if (TCG_TARGET_HAS_div_i32) { if (TCG_TARGET_HAS_rem_i32) {
tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2); tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div_i32) {
TCGv_i32 t0 = tcg_temp_new_i32();
tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
tcg_gen_mul_i32(t0, t0, arg2);
tcg_gen_sub_i32(ret, arg1, t0);
tcg_temp_free_i32(t0);
} else if (TCG_TARGET_HAS_div2_i32) { } else if (TCG_TARGET_HAS_div2_i32) {
TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i32 t0 = tcg_temp_new_i32();
tcg_gen_sari_i32(t0, arg1, 31); tcg_gen_sari_i32(t0, arg1, 31);
@ -769,8 +775,14 @@ static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{ {
if (TCG_TARGET_HAS_div_i32) { if (TCG_TARGET_HAS_rem_i32) {
tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2); tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div_i32) {
TCGv_i32 t0 = tcg_temp_new_i32();
tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
tcg_gen_mul_i32(t0, t0, arg2);
tcg_gen_sub_i32(ret, arg1, t0);
tcg_temp_free_i32(t0);
} else if (TCG_TARGET_HAS_div2_i32) { } else if (TCG_TARGET_HAS_div2_i32) {
TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i32 t0 = tcg_temp_new_i32();
tcg_gen_movi_i32(t0, 0); tcg_gen_movi_i32(t0, 0);
@ -1361,8 +1373,14 @@ static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{ {
if (TCG_TARGET_HAS_div_i64) { if (TCG_TARGET_HAS_rem_i64) {
tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2); tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div_i64) {
TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
tcg_gen_mul_i64(t0, t0, arg2);
tcg_gen_sub_i64(ret, arg1, t0);
tcg_temp_free_i64(t0);
} else if (TCG_TARGET_HAS_div2_i64) { } else if (TCG_TARGET_HAS_div2_i64) {
TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_sari_i64(t0, arg1, 63); tcg_gen_sari_i64(t0, arg1, 63);
@ -1399,8 +1417,14 @@ static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
{ {
if (TCG_TARGET_HAS_div_i64) { if (TCG_TARGET_HAS_rem_i64) {
tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2); tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div_i64) {
TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
tcg_gen_mul_i64(t0, t0, arg2);
tcg_gen_sub_i64(ret, arg1, t0);
tcg_temp_free_i64(t0);
} else if (TCG_TARGET_HAS_div2_i64) { } else if (TCG_TARGET_HAS_div2_i64) {
TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_movi_i64(t0, 0); tcg_gen_movi_i64(t0, 0);

View File

@ -27,20 +27,24 @@
*/ */
/* predefined ops */ /* predefined ops */
DEF(end, 0, 0, 0, 0) /* must be kept first */ DEF(end, 0, 0, 0, TCG_OPF_NOT_PRESENT) /* must be kept first */
DEF(nop, 0, 0, 0, 0) DEF(nop, 0, 0, 0, TCG_OPF_NOT_PRESENT)
DEF(nop1, 0, 0, 1, 0) DEF(nop1, 0, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(nop2, 0, 0, 2, 0) DEF(nop2, 0, 0, 2, TCG_OPF_NOT_PRESENT)
DEF(nop3, 0, 0, 3, 0) DEF(nop3, 0, 0, 3, TCG_OPF_NOT_PRESENT)
DEF(nopn, 0, 0, 1, 0) /* variable number of parameters */
DEF(discard, 1, 0, 0, 0) /* variable number of parameters */
DEF(nopn, 0, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(discard, 1, 0, 0, TCG_OPF_NOT_PRESENT)
DEF(set_label, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
/* variable number of parameters */
DEF(call, 0, 1, 2, TCG_OPF_CALL_CLOBBER)
DEF(set_label, 0, 0, 1, TCG_OPF_BB_END)
DEF(call, 0, 1, 2, TCG_OPF_CALL_CLOBBER) /* variable number of parameters */
DEF(br, 0, 0, 1, TCG_OPF_BB_END) DEF(br, 0, 0, 1, TCG_OPF_BB_END)
#define IMPL(X) (X ? 0 : TCG_OPF_NOT_PRESENT) #define IMPL(X) (__builtin_constant_p(X) && !(X) ? TCG_OPF_NOT_PRESENT : 0)
#if TCG_TARGET_REG_BITS == 32 #if TCG_TARGET_REG_BITS == 32
# define IMPL64 TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT # define IMPL64 TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT
#else #else
@ -66,8 +70,8 @@ DEF(sub_i32, 1, 2, 0, 0)
DEF(mul_i32, 1, 2, 0, 0) DEF(mul_i32, 1, 2, 0, 0)
DEF(div_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) DEF(div_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
DEF(divu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) DEF(divu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
DEF(rem_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) DEF(rem_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rem_i32))
DEF(remu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) DEF(remu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rem_i32))
DEF(div2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32)) DEF(div2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32))
DEF(divu2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32)) DEF(divu2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32))
DEF(and_i32, 1, 2, 0, 0) DEF(and_i32, 1, 2, 0, 0)
@ -126,8 +130,8 @@ DEF(sub_i64, 1, 2, 0, IMPL64)
DEF(mul_i64, 1, 2, 0, IMPL64) DEF(mul_i64, 1, 2, 0, IMPL64)
DEF(div_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) DEF(div_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
DEF(divu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) DEF(divu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
DEF(rem_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) DEF(rem_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rem_i64))
DEF(remu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) DEF(remu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rem_i64))
DEF(div2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64)) DEF(div2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64))
DEF(divu2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64)) DEF(divu2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64))
DEF(and_i64, 1, 2, 0, IMPL64) DEF(and_i64, 1, 2, 0, IMPL64)
@ -166,9 +170,9 @@ DEF(muls2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muls2_i64))
/* QEMU specific */ /* QEMU specific */
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
DEF(debug_insn_start, 0, 0, 2, 0) DEF(debug_insn_start, 0, 0, 2, TCG_OPF_NOT_PRESENT)
#else #else
DEF(debug_insn_start, 0, 0, 1, 0) DEF(debug_insn_start, 0, 0, 1, TCG_OPF_NOT_PRESENT)
#endif #endif
DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_END) DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_END)
DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_END) DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_END)

View File

@ -68,6 +68,24 @@ static void tcg_target_qemu_prologue(TCGContext *s);
static void patch_reloc(uint8_t *code_ptr, int type, static void patch_reloc(uint8_t *code_ptr, int type,
tcg_target_long value, tcg_target_long addend); tcg_target_long value, tcg_target_long addend);
/* The CIE and FDE header definitions will be common to all hosts. */
typedef struct {
uint32_t len __attribute__((aligned((sizeof(void *)))));
uint32_t id;
uint8_t version;
char augmentation[1];
uint8_t code_align;
uint8_t data_align;
uint8_t return_column;
} DebugFrameCIE;
typedef struct QEMU_PACKED {
uint32_t len __attribute__((aligned((sizeof(void *)))));
uint32_t cie_offset;
tcg_target_long func_start;
tcg_target_long func_len;
} DebugFrameFDEHeader;
static void tcg_register_jit_int(void *buf, size_t size, static void tcg_register_jit_int(void *buf, size_t size,
void *debug_frame, size_t debug_frame_size) void *debug_frame, size_t debug_frame_size)
__attribute__((unused)); __attribute__((unused));
@ -1160,9 +1178,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
i = 0; i = 0;
for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) { for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
const TCGOpDef *def = &tcg_op_defs[op]; const TCGOpDef *def = &tcg_op_defs[op];
if (op < INDEX_op_call if (def->flags & TCG_OPF_NOT_PRESENT) {
|| op == INDEX_op_debug_insn_start
|| (def->flags & TCG_OPF_NOT_PRESENT)) {
/* Wrong entry in op definitions? */ /* Wrong entry in op definitions? */
if (def->used) { if (def->used) {
fprintf(stderr, "Invalid op definition for %s\n", def->name); fprintf(stderr, "Invalid op definition for %s\n", def->name);
@ -2659,9 +2675,9 @@ static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
img->sym[1].st_size = buf_size; img->sym[1].st_size = buf_size;
img->di.cu_low_pc = buf; img->di.cu_low_pc = buf;
img->di.cu_high_pc = buf_size; img->di.cu_high_pc = buf + buf_size;
img->di.fn_low_pc = buf; img->di.fn_low_pc = buf;
img->di.fn_high_pc = buf_size; img->di.fn_high_pc = buf + buf_size;
#ifdef DEBUG_JIT #ifdef DEBUG_JIT
/* Enable this block to be able to debug the ELF image file creation. /* Enable this block to be able to debug the ELF image file creation.

View File

@ -60,6 +60,7 @@ typedef uint64_t TCGRegSet;
#if TCG_TARGET_REG_BITS == 32 #if TCG_TARGET_REG_BITS == 32
/* Turn some undef macros into false macros. */ /* Turn some undef macros into false macros. */
#define TCG_TARGET_HAS_div_i64 0 #define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_div2_i64 0 #define TCG_TARGET_HAS_div2_i64 0
#define TCG_TARGET_HAS_rot_i64 0 #define TCG_TARGET_HAS_rot_i64 0
#define TCG_TARGET_HAS_ext8s_i64 0 #define TCG_TARGET_HAS_ext8s_i64 0
@ -102,11 +103,13 @@ typedef uint64_t TCGRegSet;
#define TCG_TARGET_HAS_div2_i32 0 #define TCG_TARGET_HAS_div2_i32 0
#elif defined(TCG_TARGET_HAS_div2_i32) #elif defined(TCG_TARGET_HAS_div2_i32)
#define TCG_TARGET_HAS_div_i32 0 #define TCG_TARGET_HAS_div_i32 0
#define TCG_TARGET_HAS_rem_i32 0
#endif #endif
#if defined(TCG_TARGET_HAS_div_i64) #if defined(TCG_TARGET_HAS_div_i64)
#define TCG_TARGET_HAS_div2_i64 0 #define TCG_TARGET_HAS_div2_i64 0
#elif defined(TCG_TARGET_HAS_div2_i64) #elif defined(TCG_TARGET_HAS_div2_i64)
#define TCG_TARGET_HAS_div_i64 0 #define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#endif #endif
typedef enum TCGOpcode { typedef enum TCGOpcode {
@ -593,7 +596,8 @@ enum {
TCG_OPF_SIDE_EFFECTS = 0x04, TCG_OPF_SIDE_EFFECTS = 0x04,
/* Instruction operands are 64-bits (otherwise 32-bits). */ /* Instruction operands are 64-bits (otherwise 32-bits). */
TCG_OPF_64BIT = 0x08, TCG_OPF_64BIT = 0x08,
/* Instruction is optional and not implemented by the host. */ /* Instruction is optional and not implemented by the host, or insn
is generic and should not be implemened by the host. */
TCG_OPF_NOT_PRESENT = 0x10, TCG_OPF_NOT_PRESENT = 0x10,
}; };

View File

@ -59,9 +59,8 @@
#define TCG_TARGET_HAS_bswap16_i32 1 #define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1 #define TCG_TARGET_HAS_bswap32_i32 1
/* Not more than one of the next two defines must be 1. */
#define TCG_TARGET_HAS_div_i32 1 #define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_div2_i32 0 #define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1 #define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1 #define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1 #define TCG_TARGET_HAS_ext8u_i32 1
@ -83,9 +82,8 @@
#define TCG_TARGET_HAS_bswap32_i64 1 #define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1 #define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_deposit_i64 1 #define TCG_TARGET_HAS_deposit_i64 1
/* Not more than one of the next two defines must be 1. */
#define TCG_TARGET_HAS_div_i64 0 #define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_div2_i64 0 #define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_ext8s_i64 1 #define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1 #define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1 #define TCG_TARGET_HAS_ext32s_i64 1