diff options
| author | bellard <bellard> | 2005-09-03 22:03:39 +0000 |
|---|---|---|
| committer | bellard <bellard> | 2005-09-03 22:03:39 +0000 |
| commit | 3ba1190eb4b7ec2f1ec6be6aa1e983f051313796 (patch) | |
| tree | 9cf8e324d38000e2ed560dd28b529e6cd54e2b56 | |
| parent | 6f8b8887b14546f2e838dc90ad92677275663019 (diff) | |
| download | tinycc-3ba1190eb4b7ec2f1ec6be6aa1e983f051313796.tar.gz tinycc-3ba1190eb4b7ec2f1ec6be6aa1e983f051313796.tar.bz2 | |
segment override prefix support (Filip Navara)
| -rw-r--r-- | i386-asm.c | 28 |
1 files changed, 26 insertions, 2 deletions
@@ -151,6 +151,15 @@ static const uint8_t test_bits[NB_TEST_OPCODES] = { 0x0f, /* g */ }; +static const uint8_t segment_prefixes[] = { + 0x26, /* es */ + 0x2e, /* cs */ + 0x36, /* ss */ + 0x3e, /* ds */ + 0x64, /* fs */ + 0x65 /* gs */ +}; + static const ASMInstr asm_instrs[] = { #define ALT(x) x #define DEF_ASM_OP0(name, opcode) @@ -410,14 +419,15 @@ static inline void asm_modrm(int reg, Operand *op) static void asm_opcode(TCCState *s1, int opcode) { const ASMInstr *pa; - int i, modrm_index, reg, v, op1, is_short_jmp; + int i, modrm_index, reg, v, op1, is_short_jmp, has_seg_prefix; int nb_ops, s, ss; - Operand ops[MAX_OPERANDS], *pop; + Operand ops[MAX_OPERANDS], *pop, seg_prefix; int op_type[3]; /* decoded op type */ /* get operands */ pop = ops; nb_ops = 0; + has_seg_prefix = 0; for(;;) { if (tok == ';' || tok == TOK_LINEFEED) break; @@ -425,6 +435,18 @@ static void asm_opcode(TCCState *s1, int opcode) error("incorrect number of operands"); } parse_operand(s1, pop); + if (tok == ':') { + if (pop->type != OP_SEG || has_seg_prefix) { + error("incorrect prefix"); + } + seg_prefix = *pop; + has_seg_prefix = 1; + next(); + parse_operand(s1, pop); + if (!(pop->type & OP_EA)) { + error("segment prefix must be followed by memory reference"); + } + } pop++; nb_ops++; if (tok != ',') @@ -538,6 +560,8 @@ static void asm_opcode(TCCState *s1, int opcode) /* now generates the operation */ if (pa->instr_type & OPC_FWAIT) g(0x9b); + if (has_seg_prefix) + g(segment_prefixes[seg_prefix.reg]); v = pa->opcode; if (v == 0x69 || v == 0x69) { |
