tcg-target.c revision 6aaab762ef3a64fd1cd540d087fabc9c6d8387ac
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * Tiny Code Generator for QEMU
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * Copyright (c) 2008 Fabrice Bellard
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * Permission is hereby granted, free of charge, to any person obtaining a copy
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * of this software and associated documentation files (the "Software"), to deal
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * in the Software without restriction, including without limitation the rights
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * copies of the Software, and to permit persons to whom the Software is
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * furnished to do so, subject to the following conditions:
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * The above copyright notice and this permission notice shall be included in
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * all copies or substantial portions of the Software.
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync * THE SOFTWARE.
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsyncstatic const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsyncstatic const int tcg_target_reg_alloc_order[] = {
91b827c98a305956e75cb1618af6ae17e450fb88vboxsyncstatic const int tcg_target_call_iarg_regs[] = {
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsyncstatic void patch_reloc(uint8_t *code_ptr, int type,
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync/* emits stack alignment checks for strict builds. */
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsyncDECLINLINE(void) tcg_gen_stack_alignment_check(TCGContext *s)
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync# if defined(RT_STRICT) && defined(RT_OS_DARWIN) /** @todo all OSes? */
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync tcg_out8(s, 0xf7); tcg_out8(s, 0xc4); /* test %esp, 1fh */
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync#endif /* VBOX */
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync/* maximum number of register used for input function arguments */
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsyncstatic inline int tcg_target_get_call_iarg_regs_count(int flags)
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync/* parse target specific constraints */
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsyncstatic int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync const char *ct_str;
b56ca3f25c9c141f3c0855b656f8f64bbfa19496vboxsync switch(ct_str[0]) {
ct_str++;
# define LOWREGMASK(x) (x)
# define P_ADDR32 0
# define P_REXW 0
# define P_REXB_R 0
# define P_REXB_RM 0
#define ARITH_ADD 0
#define SHIFT_ROL 0
#define EXT5_INC_Ev 0
#if defined(VBOX)
unsigned rex;
rex = 0;
return len;
int rex;
rex = 0;
if (rex) {
#ifdef VBOX
#ifdef VBOX
tcg_abort();
if (rm < 0) {
if (index < 0) {
if (arg == 0) {
tcg_abort();
int rexw = 0;
if (c == ARITH_AND) {
rexw = 0;
tcg_abort();
if (val != 0) {
#ifdef VBOX
if (val != 0) {
if (l->has_value) {
if (small) {
tcg_abort();
} else if (small) {
if (const_arg2) {
if (arg2 == 0) {
int label_next;
case TCG_COND_EQ:
case TCG_COND_NE:
case TCG_COND_LT:
case TCG_COND_LE:
case TCG_COND_GT:
case TCG_COND_GE:
case TCG_COND_LTU:
case TCG_COND_LEU:
case TCG_COND_GTU:
case TCG_COND_GEU:
tcg_abort();
const int *const_args)
#ifdef VBOX
#ifdef VBOX
#if defined(CONFIG_SOFTMMU)
#include "../../softmmu_defs.h"
int rexw = 0;
+ which);
s->code_ptr++;
s->code_ptr++;
#ifdef TARGET_WORDS_BIGENDIAN
const int bswap = 0;
switch (sizeop) {
if (bswap) {
if (bswap) {
if (bswap) {
if (bswap) {
if (bswap) {
if (bswap) {
int t = datalo;
datahi = t;
if (bswap) {
tcg_abort();
static void * const vbox_ld_helpers[] = {
static void * const vbox_st_helpers[] = {
# ifdef VBOX
int addr_reg,
if (useReg2)
int addr_reg,
if (useReg2)
if (useReg2)
int opc)
int addrlo_idx;
#if defined(CONFIG_SOFTMMU)
#if defined(CONFIG_SOFTMMU)
s->code_ptr++;
switch(opc) {
tcg_abort();
#ifdef TARGET_WORDS_BIGENDIAN
const int bswap = 0;
switch (sizeop) {
if (bswap) {
if (bswap) {
if (bswap) {
} else if (bswap) {
tcg_abort();
int opc)
int addrlo_idx;
#if defined(CONFIG_SOFTMMU)
int stack_adjust;
#if defined(CONFIG_SOFTMMU)
s->code_ptr++;
stack_adjust = 0;
stack_adjust = 0;
switch(opc) {
} else if (stack_adjust != 0) {
int c, rexw = 0;
# define OP_32_64(x) \
# define OP_32_64(x) \
switch(opc) {
case INDEX_op_exit_tb:
case INDEX_op_goto_tb:
if (s->tb_jmp_offset) {
tcg_out32(s, 0);
case INDEX_op_call:
if (const_args[0]) {
case INDEX_op_jmp:
if (const_args[0]) {
case INDEX_op_br:
case INDEX_op_movi_i32:
case INDEX_op_ld32u_i64:
case INDEX_op_ld_i32:
case INDEX_op_st32_i64:
case INDEX_op_st_i32:
c = ARITH_ADD;
goto gen_arith;
c = ARITH_SUB;
goto gen_arith;
c = ARITH_AND;
goto gen_arith;
c = ARITH_OR;
goto gen_arith;
c = ARITH_XOR;
goto gen_arith;
c = SHIFT_SHL;
goto gen_shift;
c = SHIFT_SHR;
goto gen_shift;
c = SHIFT_SAR;
goto gen_shift;
c = SHIFT_ROL;
goto gen_shift;
c = SHIFT_ROR;
goto gen_shift;
case INDEX_op_brcond_i32:
case INDEX_op_setcond_i32:
case INDEX_op_qemu_ld8u:
case INDEX_op_qemu_ld8s:
case INDEX_op_qemu_ld16u:
case INDEX_op_qemu_ld16s:
case INDEX_op_qemu_ld32u:
case INDEX_op_qemu_ld32:
case INDEX_op_qemu_ld64:
case INDEX_op_qemu_st8:
case INDEX_op_qemu_st16:
case INDEX_op_qemu_st32:
case INDEX_op_qemu_st64:
case INDEX_op_brcond2_i32:
case INDEX_op_setcond2_i32:
case INDEX_op_mulu2_i32:
case INDEX_op_add2_i32:
case INDEX_op_sub2_i32:
case INDEX_op_movi_i64:
case INDEX_op_ld32s_i64:
case INDEX_op_ld_i64:
case INDEX_op_st_i64:
case INDEX_op_qemu_ld32s:
case INDEX_op_brcond_i64:
case INDEX_op_setcond_i64:
case INDEX_op_bswap64_i64:
case INDEX_op_ext32u_i64:
case INDEX_op_ext32s_i64:
tcg_abort();
{ INDEX_op_exit_tb, { } },
{ INDEX_op_goto_tb, { } },
{ INDEX_op_br, { } },
static int tcg_target_callee_save_regs[] = {
# ifndef VBOX
# ifdef VBOX
#if !defined(CONFIG_USER_ONLY)
tcg_abort();