1 /** 2 * Copyright (c)2004 Jean-Christophe Hoelt <jeko@ios-software.com> 3 */ 4 5 #include <stdlib.h> 6 #include <string.h> 7 8 #define JITC_MAXLABEL 1024 9 #define JITC_LABEL_SIZE 64 10 11 /** 12 * low level macros 13 */ 14 15 /* {{{ Registres Generaux */ 16 #define EAX 0 17 #define ECX 1 18 #define EDX 2 19 #define EBX 3 20 #define ESP 4 21 #define EBP 5 22 #define ESI 6 23 #define EDI 7 24 /* }}} */ 25 /* {{{ Registres MMX */ 26 #define MM0 0 27 #define MM1 1 28 #define MM2 2 29 #define MM3 3 30 #define MM4 4 31 #define MM5 5 32 #define MM6 6 33 #define MM7 7 34 /* }}} */ 35 /* {{{ Registres SSE*/ 36 #define XMM0 0 37 #define XMM1 1 38 #define XMM2 2 39 #define XMM3 3 40 #define XMM4 4 41 #define XMM5 5 42 #define XMM6 6 43 #define XMM7 7 44 /* }}} */ 45 /* {{{ Alias aux registres */ 46 #define R0 0 47 #define R1 1 48 #define R2 2 49 #define R3 3 50 #define R4 4 51 #define R5 5 52 #define R6 6 53 #define R7 7 54 /* }}} */ 55 56 /* {{{ Conditions */ 57 #define COND_OVERFLOW 0 58 #define COND_NO_OVERFLOW 1 59 #define COND_BELOW 2 60 #define COND_NOT_BELOW 3 61 #define COND_EQUAL 4 62 #define COND_ZERO 4 63 #define COND_NOT_EQUAL 5 64 #define COND_NOT_ZERO 5 65 #define COND_NOT_ABOVE 6 66 #define COND_ABOVE 7 67 #define COND_SIGN 8 68 #define COND_NOT_SIGN 9 69 #define COND_EVEN 10 70 #define COND_ODD 11 71 #define COND_LESS_THAN 12 72 #define COND_GREATER_EQUAL 13 73 #define COND_LESS_EQUAL 14 74 #define COND_GREATER_THAN 15 75 /* }}} */ 76 77 typedef int (*JitcFunc)(void); 78 79 typedef struct _LABEL_ADDR { 80 char label[JITC_LABEL_SIZE]; 81 int address; 82 } LabelAddr; 83 84 typedef struct _JITC_X86_ENV { 85 unsigned char *_memory; 86 unsigned char *memory; 87 unsigned int used; 88 89 int nbUsedLabel; 90 int nbKnownLabel; 91 LabelAddr *usedLabel; 92 LabelAddr *knownLabel; 93 } JitcX86Env; 94 95 #define DISPLAY_GENCODE 96 /*#define DISPLAY_GENCODE_HEXA*/ 97 98 #ifdef DISPLAY_GENCODE_HEXA 99 #define JITC_ADD_UCHAR(jitc,op) printf(" 0x%02x", op) && (jitc->memory[jitc->used++]=op) 100 #else 101 #define JITC_ADD_UCHAR(jitc,op) (jitc->memory[jitc->used++]=op) 102 #endif 103 104 #define JITC_ADD_USHORT(jitc,i) { JITC_ADD_UCHAR(jitc,i&0xff); JITC_ADD_UCHAR(jitc,(i>>8)&0xff); } 105 #define JITC_ADD_UINT(jitc,i) { \ 106 JITC_ADD_UCHAR(jitc,i&0xff); \ 107 JITC_ADD_UCHAR(jitc,(i>>8)&0xff); \ 108 JITC_ADD_UCHAR(jitc,(i>>16)&0xff); \ 109 JITC_ADD_UCHAR(jitc,(i>>24)&0xff); \ 110 } 111 #define JITC_ADD_2UCHAR(jitc,op1,op2) {JITC_ADD_UCHAR(jitc,op1); JITC_ADD_UCHAR(jitc,op2);} 112 113 #define JITC_MODRM(jitc,mod,reg,rm) { JITC_ADD_UCHAR(jitc,((int)mod<<6)|((int)reg<<3)|((int)rm)); } 114 115 /* special values for R/M */ 116 #define JITC_RM_DISP32 0x05 117 118 #define JITC_MOD_pREG_REG 0x00 119 #define JITC_MOD_disp8REG_REG 0x01 120 #define JITC_MOD_disp32REG_REG 0x02 121 #define JITC_MOD_REG_REG 0x03 122 /* cf 24319101 p.27 */ 123 124 #define JITC_OP_REG_REG(jitc,op,dest,src) { JITC_ADD_UCHAR(jitc,op); JITC_ADD_UCHAR(jitc,0xc0+(src<<3)+dest); } 125 #define JITC_OP_REG_pREG(jitc,op,dest,src) { JITC_ADD_UCHAR(jitc,op); JITC_ADD_UCHAR(jitc,(dest<<3)+src); } 126 #define JITC_OP_pREG_REG(jitc,op,dest,src) { JITC_ADD_UCHAR(jitc,op); JITC_ADD_UCHAR(jitc,(src<<3)+dest); } 127 128 /** 129 * "high" level macro 130 */ 131 132 #define JITC_LOAD_REG_IMM32(jitc,reg,imm32) { JITC_ADD_UCHAR (jitc,0xb8+reg); JITC_ADD_UINT(jitc,(int)(imm32)); } 133 #define JITC_LOAD_REG_REG(jitc,dest,src) { JITC_OP_REG_REG (jitc,0x89,dest,src); } 134 135 #define JITC_LOAD_REG_pREG(jitc,dest,src) { JITC_OP_REG_pREG(jitc,0x8b,dest,src); } 136 #define JITC_LOAD_pREG_REG(jitc,dest,src) { JITC_OP_pREG_REG(jitc,0x89,dest,src); } 137 138 #define JITC_DEC_REG(jitc,reg) { JITC_ADD_UCHAR (jitc,0x48+reg); } 139 #define JITC_INC_REG(jitc,reg) { JITC_ADD_UCHAR (jitc,0x40+reg); } 140 141 #define JITC_ADD_REG_REG(jitc,dest,src) { JITC_OP_REG_REG (jitc,0x01,dest,src); } 142 #define JITC_ADD_REG_IMM32(jitc,reg,imm32) { JITC_ADD_UCHAR (jitc,0x81);\ 143 JITC_ADD_UCHAR (jitc,0xc0+reg);\ 144 JITC_ADD_UINT (jitc,(int)imm32); } 145 146 #define JITC_AND_REG_REG(jitc,dest,src) { JITC_OP_REG_REG (jitc,0x21,dest,src); } 147 #define JITC_CMP_REG_REG(jitc,dest,src) { JITC_OP_REG_REG (jitc,0x39,dest,src); } 148 #define JITC_CMP_REG_IMM32(jitc,reg,imm32) { JITC_ADD_2UCHAR (jitc,0x81,0xf8+reg); \ 149 JITC_ADD_UINT (jitc,(int)imm32); } 150 151 #define JITC_IDIV_EAX_REG(jitc,reg) { JITC_ADD_2UCHAR(jitc, 0xf7, 0xf8+reg); } 152 #define JITC_IMUL_EAX_REG(jitc,reg) { JITC_ADD_2UCHAR(jitc, 0xf7, 0xe8+reg); } 153 154 /*#define JITC_SUB_REG_REG(jitc,dest,src) { JITC_OP_REG_REG (jitc,0x29,dest,src); } 155 #define JITC_SUB_EAX_IMM32(jitc,imm32) { JITC_ADD_UCHAR (jitc,0x2d); JITC_ADD_UINT(jitc,(int)imm32); } 156 #define JITC_SUB_REG_IMM32(jitc,reg,imm32) { JITC_ADD_2UCHAR (jitc,0x81, 0xe8+reg);\ 157 JITC_ADD_UINT (jitc,(int)imm32); }*/ 158 #define JITC_SUB_REG_IMM8(jitc,reg,imm8) { JITC_ADD_2UCHAR (jitc,0x83, 0xe8+reg);\ 159 JITC_ADD_UCHAR(jitc,imm8); } 160 161 /* Floating points */ 162 163 #define JITC_FLD_pIMM32(jitc,address) { JITC_ADD_UCHAR (jitc, 0xD9); \ 164 JITC_MODRM (jitc, 0x00, 0x00,JITC_RM_DISP32); \ 165 JITC_ADD_UINT(jitc,(int)(address)); } 166 #define JITC_FLD_STi(jict,reg) { JITC_ADD_2UCHAR (jitc, 0xD9, 0xC0+reg); } 167 168 #define JITC_FST_pIMM32(jitc,address) { JITC_ADD_UCHAR (jitc, 0xD9); \ 169 JITC_MODRM (jitc, 0x00, 0x02,JITC_RM_DISP32); \ 170 JITC_ADD_UINT(jitc,(int)(ADDRess)); } 171 #define JITC_FST_STi(jict,reg) { JITC_ADD_2UCHAR (jitc, 0xDD, 0xD0+reg); } 172 173 #define JITC_FSTP_pIMM32(jitc,address) { JITC_ADD_UCHAR (jitc, 0xD9); \ 174 JITC_MODRM (jitc, 0x00, 0x03, JITC_RM_DISP32); \ 175 JITC_ADD_UINT(jitc,(int)(address)); } 176 #define JITC_FSTP_STi(jict,reg) { JITC_ADD_2UCHAR (jitc, 0xDD, 0xD8+reg); } 177 178 #define JITC_FADD 179 180 /* Jumps */ 181 182 #define JITC_ADD_LABEL(jitc,label) { jitc_add_known_label(jitc,label,jitc->used); } 183 184 #define JITC_JUMP(jitc,offset) { JITC_ADD_UCHAR(jitc,0xe9); JITC_ADD_UINT(jitc,offset); } 185 #define JITC_JUMP_LABEL(jitc,label) { jitc_add_used_label(jitc,label,jitc->used+1); JITC_JUMP(jitc,0); } 186 #define JITC_JUMP_COND(jitc,cond,offset) { JITC_ADD_UCHAR(jitc,0x0f);\ 187 JITC_ADD_UCHAR(jitc,0x80+cond);\ 188 JITC_ADD_UINT(jitc,offset); } 189 #define JITC_JUMP_COND_LABEL(jitc,cond,label) { jitc_add_used_label(jitc,label,jitc->used+2); JITC_JUMP_COND(jitc,cond,0); } 190 #define JITC_CALL(jitc,function) { int __offset__ = (int)function - (int)(&jitc->memory[jitc->used+5]);\ 191 JITC_ADD_UCHAR(jitc,0xe8); JITC_ADD_UINT(jitc,__offset__); } 192 /*#define JITC_CALL_pREG(jitc,reg) { JITC_ADD_UCHAR(jitc,0xff); JITC_ADD_UCHAR(jitc,0xd0+reg); } 193 #define JITC_CALL_LABEL(jitc,label) { jitc_add_used_label(jitc,label,jitc->used+1); JITC_CALL(jitc,0); }*/ 194 195 /* save all registers (except EAX,ESP,EBP) */ 196 #define JITC_PUSH_ALL(jitc) { jitc_add(jitc,"push ecx"); jitc_add(jitc,"push edx"); jitc_add(jitc,"push ebx"); \ 197 jitc_add(jitc,"push esi"); jitc_add(jitc,"push edi"); } 198 199 /* restore all registers (except EAX,ESP,EBP) */ 200 #define JITC_POP_ALL(jitc) { jitc_add(jitc,"pop edi"); jitc_add(jitc,"pop esi"); jitc_add(jitc,"pop ebx"); \ 201 jitc_add(jitc,"pop edx"); jitc_add(jitc,"pop ecx"); } 202 203 /* public methods */ 204 JitcX86Env *jitc_x86_env_new(int memory_size); 205 JitcFunc jitc_prepare_func(JitcX86Env *jitc); 206 void jitc_add(JitcX86Env *jitc, const char *instr, ...); 207 void jitc_validate_func(JitcX86Env *jitc); 208 void jitc_x86_delete(JitcX86Env *jitc); 209 210 211 /* private methods */ 212 void jitc_add_used_label(JitcX86Env *jitc, char *label, int where); 213 void jitc_add_known_label(JitcX86Env *jitc, char *label, int where); 214 void jitc_resolve_labels(JitcX86Env *jitc); 215