📄 amd64-codegen.h
字号:
/* * amd64-codegen.h: Macros for generating amd64 code * * Authors: * Paolo Molaro (lupus@ximian.com) * Intel Corporation (ORP Project) * Sergey Chaban (serge@wildwestsoftware.com) * Dietmar Maurer (dietmar@ximian.com) * Patrik Torstensson * Zalman Stern * * Copyright (C) 2000 Intel Corporation. All rights reserved. * Copyright (C) 2001, 2002 Ximian, Inc. */#ifndef AMD64_H#define AMD64_Htypedef enum { AMD64_RAX = 0, AMD64_RCX = 1, AMD64_RDX = 2, AMD64_RBX = 3, AMD64_RSP = 4, AMD64_RBP = 5, AMD64_RSI = 6, AMD64_RDI = 7, AMD64_R8 = 8, AMD64_R9 = 9, AMD64_R10 = 10, AMD64_R11 = 11, AMD64_R12 = 12, AMD64_R13 = 13, AMD64_R14 = 14, AMD64_R15 = 15, AMD64_RIP = 16, AMD64_NREG} AMD64_Reg_No;typedef enum { AMD64_XMM0 = 0, AMD64_XMM1 = 1, AMD64_XMM2 = 2, AMD64_XMM3 = 3, AMD64_XMM4 = 4, AMD64_XMM5 = 5, AMD64_XMM6 = 6, AMD64_XMM7 = 7, AMD64_XMM8 = 8, AMD64_XMM9 = 9, AMD64_XMM10 = 10, AMD64_XMM11 = 11, AMD64_XMM12 = 12, AMD64_XMM13 = 13, AMD64_XMM14 = 14, AMD64_XMM15 = 15, AMD64_XMM_NREG = 16,} AMD64_XMM_Reg_No;typedef enum{ AMD64_REX_B = 1, /* The register in r/m field, base register in SIB byte, or reg in opcode is 8-15 rather than 0-7 */ AMD64_REX_X = 2, /* The index register in SIB byte is 8-15 rather than 0-7 */ AMD64_REX_R = 4, /* The reg field of ModRM byte is 8-15 rather than 0-7 */ AMD64_REX_W = 8 /* Opeartion is 64-bits instead of 32 (default) or 16 (with 0x66 prefix) */} AMD64_REX_Bits;#define AMD64_CALLEE_REGS ((1<<AMD64_RAX) | (1<<AMD64_RCX) | (1<<AMD64_RDX) | (1<<AMD64_RSI) | (1<<AMD64_RDI) | (1<<AMD64_R8) | (1<<AMD64_R9) | (1<<AMD64_R10))#define AMD64_IS_CALLEE_REG(reg) (AMD64_CALLEE_REGS & (1 << (reg)))#define AMD64_ARGUMENT_REGS ((1<<AMD64_RDI) | (1<<AMD64_RSI) | (1<<AMD64_RDX) | (1<<AMD64_RCX) | (1<<AMD64_R8) | (1<<AMD64_R9))#define AMD64_IS_ARGUMENT_REG(reg) (AMD64_ARGUMENT_REGS & (1 << (reg)))#define AMD64_CALLEE_SAVED_REGS ((1<<AMD64_RBX) | (1<<AMD64_R12) | (1<<AMD64_R13) | (1<<AMD64_R14) | (1<<AMD64_R15) | (1<<AMD64_RBP))#define AMD64_IS_CALLEE_SAVED_REG(reg) (AMD64_CALLEE_SAVED_REGS & (1 << (reg)))#define AMD64_REX(bits) ((unsigned char)(0x40 | (bits)))#define amd64_emit_rex(inst, width, reg_modrm, reg_index, reg_rm_base_opcode) do \ { \ unsigned char _amd64_rex_bits = \ (((width) > 4) ? AMD64_REX_W : 0) | \ (((reg_modrm) > 7) ? AMD64_REX_R : 0) | \ (((reg_index) > 7) ? AMD64_REX_X : 0) | \ (((reg_rm_base_opcode) > 7) ? AMD64_REX_B : 0); \ if ((_amd64_rex_bits != 0) || (((width) == 1))) *(inst)++ = AMD64_REX(_amd64_rex_bits); \ } while (0)typedef union { long val; unsigned char b [8];} amd64_imm_buf;#include "x86-codegen.h"#define amd64_bswap32(inst,reg) \ do { \ *(inst)++ = 0x0f; \ *(inst)++ = (unsigned char)0xc8 + (reg); \ } while (0)/* In 64 bit mode, all registers have a low byte subregister */#undef X86_IS_BYTE_REG#define X86_IS_BYTE_REG(reg) 1#define amd64_modrm_mod(modrm) ((modrm) >> 6)#define amd64_modrm_reg(modrm) (((modrm) >> 3) & 0x7)#define amd64_modrm_rm(modrm) ((modrm) & 0x7)#define amd64_rex_r(rex) ((((rex) >> 2) & 0x1) << 3)#define amd64_rex_x(rex) ((((rex) >> 1) & 0x1) << 3)#define amd64_rex_b(rex) ((((rex) >> 0) & 0x1) << 3)#define amd64_is_imm32(val) ((glong)val >= -((glong)1<<31) && (glong)val <= (((glong)1<<31)-1))#define x86_imm_emit64(inst,imm) \ do { \ amd64_imm_buf imb; imb.val = (long) (imm); \ *(inst)++ = imb.b [0]; \ *(inst)++ = imb.b [1]; \ *(inst)++ = imb.b [2]; \ *(inst)++ = imb.b [3]; \ *(inst)++ = imb.b [4]; \ *(inst)++ = imb.b [5]; \ *(inst)++ = imb.b [6]; \ *(inst)++ = imb.b [7]; \ } while (0)#define amd64_membase_emit(inst,reg,basereg,disp) do { \ if ((basereg) == AMD64_RIP) { \ x86_address_byte ((inst), 0, (reg)&0x7, 5); \ x86_imm_emit32 ((inst), (disp)); \ } \ else \ x86_membase_emit ((inst),(reg)&0x7, (basereg)&0x7, (disp)); \} while (0)#define amd64_alu_reg_imm_size(inst,opc,reg,imm,size) \ do { \ if ((reg) == X86_EAX) { \ amd64_emit_rex(inst, size, 0, 0, 0); \ *(inst)++ = (((unsigned char)(opc)) << 3) + 5; \ x86_imm_emit32 ((inst), (imm)); \ break; \ } \ if (x86_is_imm8((imm))) { \ amd64_emit_rex(inst, size, 0, 0, (reg)); \ *(inst)++ = (unsigned char)0x83; \ x86_reg_emit ((inst), (opc), (reg)); \ x86_imm_emit8 ((inst), (imm)); \ } else { \ amd64_emit_rex(inst, size, 0, 0, (reg)); \ *(inst)++ = (unsigned char)0x81; \ x86_reg_emit ((inst), (opc), (reg)); \ x86_imm_emit32 ((inst), (imm)); \ } \ } while (0)#define amd64_alu_reg_imm(inst,opc,reg,imm) amd64_alu_reg_imm_size((inst),(opc),(reg),(imm),8)#define amd64_alu_reg_reg_size(inst,opc,dreg,reg,size) \ do { \ amd64_emit_rex(inst, size, (dreg), 0, (reg)); \ *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \ x86_reg_emit ((inst), (dreg), (reg)); \ } while (0)#define amd64_alu_reg_reg(inst,opc,dreg,reg) amd64_alu_reg_reg_size ((inst),(opc),(dreg),(reg),8)#define amd64_mov_regp_reg(inst,regp,reg,size) \ do { \ if ((size) == 2) \ *(inst)++ = (unsigned char)0x66; \ amd64_emit_rex(inst, (size), (reg), 0, (regp)); \ switch ((size)) { \ case 1: *(inst)++ = (unsigned char)0x88; break; \ case 2: case 4: case 8: *(inst)++ = (unsigned char)0x89; break; \ default: assert (0); \ } \ x86_regp_emit ((inst), (reg), (regp)); \ } while (0)#define amd64_mov_membase_reg(inst,basereg,disp,reg,size) \ do { \ if ((size) == 2) \ *(inst)++ = (unsigned char)0x66; \ amd64_emit_rex(inst, (size), (reg), 0, (basereg)); \ switch ((size)) { \ case 1: *(inst)++ = (unsigned char)0x88; break; \ case 2: case 4: case 8: *(inst)++ = (unsigned char)0x89; break; \ default: assert (0); \ } \ x86_membase_emit ((inst), ((reg)&0x7), ((basereg)&0x7), (disp)); \ } while (0)#define amd64_mov_reg_reg(inst,dreg,reg,size) \ do { \ if ((size) == 2) \ *(inst)++ = (unsigned char)0x66; \ amd64_emit_rex(inst, (size), (dreg), 0, (reg)); \ switch ((size)) { \ case 1: *(inst)++ = (unsigned char)0x8a; break; \ case 2: case 4: case 8: *(inst)++ = (unsigned char)0x8b; break; \ default: assert (0); \ } \ x86_reg_emit ((inst), (dreg), (reg)); \ } while (0)#define amd64_mov_reg_mem(inst,reg,mem,size) \ do { \ if ((size) == 2) \ *(inst)++ = (unsigned char)0x66; \ amd64_emit_rex(inst, (size), (reg), 0, 0); \ switch ((size)) { \ case 1: *(inst)++ = (unsigned char)0x8a; break; \ case 2: case 4: case 8: *(inst)++ = (unsigned char)0x8b; break; \ default: assert (0); \ } \ x86_address_byte ((inst), 0, (reg), 4); \ x86_address_byte ((inst), 0, 4, 5); \ x86_imm_emit32 ((inst), (mem)); \ } while (0)#define amd64_mov_reg_membase(inst,reg,basereg,disp,size) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -