Mercurial > hg > qcc
comparison i386/asm.c @ 553:4533aa54ffcf
More simplification and attacking warnings.
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 21 Jan 2008 00:29:43 -0600 |
parents | d8b3fa09ca5d |
children | 9414324cc68a |
comparison
equal
deleted
inserted
replaced
552:40ec0942b7f4 | 553:4533aa54ffcf |
---|---|
94 int8_t reg2; /* second register, -1 if none */ | 94 int8_t reg2; /* second register, -1 if none */ |
95 uint8_t shift; | 95 uint8_t shift; |
96 ExprValue e; | 96 ExprValue e; |
97 } Operand; | 97 } Operand; |
98 | 98 |
99 static const uint8_t reg_to_size[5] = { | 99 static uint8_t reg_to_size[5] = { |
100 [OP_REG8] = 0, | 100 [OP_REG8] = 0, |
101 [OP_REG16] = 1, | 101 [OP_REG16] = 1, |
102 [OP_REG32] = 2, | 102 [OP_REG32] = 2, |
103 }; | 103 }; |
104 | 104 |
105 #define WORD_PREFIX_OPCODE 0x66 | 105 #define WORD_PREFIX_OPCODE 0x66 |
106 | 106 |
107 #define NB_TEST_OPCODES 30 | 107 #define NB_TEST_OPCODES 30 |
108 | 108 |
109 static const uint8_t test_bits[NB_TEST_OPCODES] = { | 109 static uint8_t test_bits[NB_TEST_OPCODES] = { |
110 0x00, /* o */ | 110 0x00, /* o */ |
111 0x01, /* no */ | 111 0x01, /* no */ |
112 0x02, /* b */ | 112 0x02, /* b */ |
113 0x02, /* c */ | 113 0x02, /* c */ |
114 0x02, /* nae */ | 114 0x02, /* nae */ |
137 0x0e, /* ng */ | 137 0x0e, /* ng */ |
138 0x0f, /* nle */ | 138 0x0f, /* nle */ |
139 0x0f, /* g */ | 139 0x0f, /* g */ |
140 }; | 140 }; |
141 | 141 |
142 static const uint8_t segment_prefixes[] = { | 142 static uint8_t segment_prefixes[] = { |
143 0x26, /* es */ | 143 0x26, /* es */ |
144 0x2e, /* cs */ | 144 0x2e, /* cs */ |
145 0x36, /* ss */ | 145 0x36, /* ss */ |
146 0x3e, /* ds */ | 146 0x3e, /* ds */ |
147 0x64, /* fs */ | 147 0x64, /* fs */ |
148 0x65 /* gs */ | 148 0x65 /* gs */ |
149 }; | 149 }; |
150 | 150 |
151 static const ASMInstr asm_instrs[] = { | 151 static ASMInstr asm_instrs[] = { |
152 #define ALT(x) x | 152 #define ALT(x) x |
153 #define DEF_ASM_OP0(name, opcode) | 153 #define DEF_ASM_OP0(name, opcode) |
154 #define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 }, | 154 #define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 }, |
155 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }}, | 155 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }}, |
156 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }}, | 156 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }}, |
159 | 159 |
160 /* last operation */ | 160 /* last operation */ |
161 { 0, }, | 161 { 0, }, |
162 }; | 162 }; |
163 | 163 |
164 static const uint16_t op0_codes[] = { | 164 static uint16_t op0_codes[] = { |
165 #define ALT(x) | 165 #define ALT(x) |
166 #define DEF_ASM_OP0(x, opcode) opcode, | 166 #define DEF_ASM_OP0(x, opcode) opcode, |
167 #define DEF_ASM_OP0L(name, opcode, group, instr_type) | 167 #define DEF_ASM_OP0L(name, opcode, group, instr_type) |
168 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) | 168 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) |
169 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) | 169 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) |
216 | 216 |
217 static void parse_operand(TCCState *s1, Operand *op) | 217 static void parse_operand(TCCState *s1, Operand *op) |
218 { | 218 { |
219 ExprValue e; | 219 ExprValue e; |
220 int reg, indir; | 220 int reg, indir; |
221 const char *p; | 221 char *p; |
222 | 222 |
223 indir = 0; | 223 indir = 0; |
224 if (tok == '*') { | 224 if (tok == '*') { |
225 next(); | 225 next(); |
226 indir = OP_INDIR; | 226 indir = OP_INDIR; |
406 } | 406 } |
407 } | 407 } |
408 | 408 |
409 static void asm_opcode(TCCState *s1, int opcode) | 409 static void asm_opcode(TCCState *s1, int opcode) |
410 { | 410 { |
411 const ASMInstr *pa; | 411 ASMInstr *pa; |
412 int i, modrm_index, reg, v, op1, is_short_jmp, has_seg_prefix; | 412 int i, modrm_index, reg, v, op1, is_short_jmp, has_seg_prefix; |
413 int nb_ops, s, ss; | 413 int nb_ops, s, ss; |
414 Operand ops[MAX_OPERANDS], *pop, seg_prefix; | 414 Operand ops[MAX_OPERANDS], *pop, seg_prefix; |
415 int op_type[3]; /* decoded op type */ | 415 int op_type[3]; /* decoded op type */ |
416 | 416 |
718 #define NB_SAVED_REGS 3 | 718 #define NB_SAVED_REGS 3 |
719 #define NB_ASM_REGS 8 | 719 #define NB_ASM_REGS 8 |
720 | 720 |
721 /* return the constraint priority (we allocate first the lowest | 721 /* return the constraint priority (we allocate first the lowest |
722 numbered constraints) */ | 722 numbered constraints) */ |
723 static inline int constraint_priority(const char *str) | 723 static inline int constraint_priority(char *str) |
724 { | 724 { |
725 int priority, c, pr; | 725 int priority, c, pr; |
726 | 726 |
727 /* we take the lowest priority */ | 727 /* we take the lowest priority */ |
728 priority = 0; | 728 priority = 0; |
765 priority = pr; | 765 priority = pr; |
766 } | 766 } |
767 return priority; | 767 return priority; |
768 } | 768 } |
769 | 769 |
770 static const char *skip_constraint_modifiers(const char *p) | 770 static char *skip_constraint_modifiers(char *p) |
771 { | 771 { |
772 while (*p == '=' || *p == '&' || *p == '+' || *p == '%') | 772 while (*p == '=' || *p == '&' || *p == '+' || *p == '%') |
773 p++; | 773 p++; |
774 return p; | 774 return p; |
775 } | 775 } |
779 | 779 |
780 #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) | 780 #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) |
781 | 781 |
782 static void asm_compute_constraints(ASMOperand *operands, | 782 static void asm_compute_constraints(ASMOperand *operands, |
783 int nb_operands, int nb_outputs, | 783 int nb_operands, int nb_outputs, |
784 const uint8_t *clobber_regs, | 784 uint8_t *clobber_regs, |
785 int *pout_reg) | 785 int *pout_reg) |
786 { | 786 { |
787 ASMOperand *op; | 787 ASMOperand *op; |
788 int sorted_op[MAX_ASM_OPERANDS]; | 788 int sorted_op[MAX_ASM_OPERANDS]; |
789 int i, j, k, p1, p2, tmp, reg, c, reg_mask; | 789 int i, j, k, p1, p2, tmp, reg, c, reg_mask; |
790 const char *str; | 790 char *str; |
791 uint8_t regs_allocated[NB_ASM_REGS]; | 791 uint8_t regs_allocated[NB_ASM_REGS]; |
792 | 792 |
793 /* init fields */ | 793 /* init fields */ |
794 for(i=0;i<nb_operands;i++) { | 794 for(i=0;i<nb_operands;i++) { |
795 op = &operands[i]; | 795 op = &operands[i]; |
1174 g(0x58 + reg); | 1174 g(0x58 + reg); |
1175 } | 1175 } |
1176 } | 1176 } |
1177 } | 1177 } |
1178 | 1178 |
1179 static void asm_clobber(uint8_t *clobber_regs, const char *str) | 1179 static void asm_clobber(uint8_t *clobber_regs, char *str) |
1180 { | 1180 { |
1181 int reg; | 1181 int reg; |
1182 TokenSym *ts; | 1182 TokenSym *ts; |
1183 | 1183 |
1184 if (!strcmp(str, "memory") || | 1184 if (!strcmp(str, "memory") || |