/* parse target specific constraints */ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) { const char *ct_str; ct_str = *pct_str; switch (ct_str[0]) { case 'r': ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xffffffff); break; case 'L': /* qemu_ld/st constraint */ ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xffffffff); // Helper args tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0); tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1); tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2); break; case 'I': ct->ct |= TCG_CT_CONST_S11; break; case 'J': ct->ct |= TCG_CT_CONST_S13; break; default: return -1; } ct_str++; *pct_str = ct_str; return 0; }
static void tcg_target_init(TCGContext *s) { #if defined(CONFIG_DEBUG_TCG_INTERPRETER) const char *envval = getenv("DEBUG_TCG"); if (envval) { qemu_set_log(strtol(envval, NULL, 0)); } #endif /* The current code uses uint8_t for tcg operations. */ assert(tcg_op_defs_max <= UINT8_MAX); /* Registers available for 32 bit operations. */ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, BIT(TCG_TARGET_NB_REGS) - 1); /* Registers available for 64 bit operations. */ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, BIT(TCG_TARGET_NB_REGS) - 1); /* TODO: Which registers should be set here? */ tcg_regset_set32(tcg_target_call_clobber_regs, 0, BIT(TCG_TARGET_NB_REGS) - 1); tcg_regset_clear(s->reserved_regs); tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); tcg_add_target_add_op_defs(tcg_target_op_defs); /* We use negative offsets from "sp" so that we can distinguish stores that might pretend to be call arguments. */ tcg_set_frame(s, TCG_REG_CALL_STACK, -CPU_TEMP_BUF_NLONGS * sizeof(long), CPU_TEMP_BUF_NLONGS * sizeof(long)); }
/* parse target specific constraints */ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) { const char *ct_str; ct_str = *pct_str; switch(ct_str[0]) { case 'a': ct->ct |= TCG_CT_REG; tcg_regset_set_reg(ct->u.regs, TCG_REG_EAX); break; case 'b': ct->ct |= TCG_CT_REG; tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX); break; case 'c': ct->ct |= TCG_CT_REG; tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX); break; case 'd': ct->ct |= TCG_CT_REG; tcg_regset_set_reg(ct->u.regs, TCG_REG_EDX); break; case 'S': ct->ct |= TCG_CT_REG; tcg_regset_set_reg(ct->u.regs, TCG_REG_ESI); break; case 'D': ct->ct |= TCG_CT_REG; tcg_regset_set_reg(ct->u.regs, TCG_REG_EDI); break; case 'q': ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xf); break; case 'r': ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xff); break; /* qemu_ld/st address constraint */ case 'L': ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xff); tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX); tcg_regset_reset_reg(ct->u.regs, TCG_REG_EDX); break; default: return -1; } ct_str++; *pct_str = ct_str; return 0; }
void tcg_target_init(TCGContext *s) { /* fail safe */ if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) tcg_abort(); tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff); tcg_regset_set32(tcg_target_call_clobber_regs, 0, (1 << TCG_REG_EAX) | (1 << TCG_REG_EDX) | (1 << TCG_REG_ECX)); tcg_regset_clear(s->reserved_regs); tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP); tcg_add_target_add_op_defs(x86_op_defs); }
/* Parse target specific constraints. */ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) { const char *ct_str = *pct_str; switch (ct_str[0]) { case 'r': case 'L': /* qemu_ld constraint */ case 'S': /* qemu_st constraint */ ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, BIT(TCG_TARGET_NB_REGS) - 1); break; default: return -1; } ct_str++; *pct_str = ct_str; return 0; }