|
|
1.1 root 1: #include "as.h"
2: #include "flonum.h"
3: #include "expr.h"
4: #include "i386.h"
5:
6: #include "i386-opcode.h"
7: /* these are to get rid of the compiler "defined but not used" messages */
8: const reg_entry **use_it1 = &i386_regtab_end;
9: const seg_entry *use_it2 = &cs;
10: const seg_entry *use_it3 = &es;
11: const seg_entry *use_it4 = &fs;
12: const seg_entry *use_it5 = &gs;
13: const seg_entry **use_it6 = one_byte_segment_defaults;
14: const seg_entry **use_it7 = two_byte_segment_defaults;
15:
16: static char **get_operand(
17: unsigned long type);
18: static char *get_suffix(
19: unsigned long type);
20:
21: void
22: main(void)
23: {
24: const template *t;
25: const prefix_entry *p;
26: long prefix;
27:
28: unsigned long i, j, type0, type1;
29: char **op0, **op1;
30: char *suffix;
31:
32: for(t = i386_optab; t < i386_optab_end; t++){
33: /*
34: * Don't use the table entries that are prefixes and not
35: * instructions.
36: */
37: prefix = 0;
38: for(p = i386_prefixtab; p < i386_prefixtab_end; p++){
39: prefix = (p->prefix_code == t->base_opcode);
40: if(prefix)
41: break;
42: }
43: if(prefix)
44: continue;
45: /*
46: * The string instructions with operands take only specific
47: * operands and are not checked here.
48: */
49: if(t->operands != 0 && IS_STRING_INSTRUCTION(t->base_opcode))
50: continue;
51:
52: if(t->operands == 0){
53: if((t->opcode_modifier & W) == 0) {
54: printf("\t%s\n", t->name);
55: }
56: else{
57: printf("\t%sb\n", t->name);
58: printf("\t%sw\n", t->name);
59: printf("\t%sl\n", t->name);
60: }
61: }
62:
63: if(t->operands == 1){
64: for(i = 0; i < 32; i++){
65: type0 = 1 << i;
66: if((type0 & t->operand_types[0]) == 0)
67: continue;
68:
69: /* These only take byte displacement */
70: if(IS_LOOP_ECX_TIMES(t->base_opcode) &&
71: (type0 == Disp16 || type0 == Disp32))
72: continue;
73:
74: /* These only take byte displacement */
75: if((strcmp(t->name, "jcxz") == 0 ||
76: strcmp(t->name, "jecxz") == 0) &&
77: (type0 == Disp16 || type0 == Disp32))
78: continue;
79:
80: if(type0 == Disp8 &&
81: ((t->operand_types[0] & (Disp16 | Disp32)) != 0))
82: continue;
83:
84: suffix = "";
85: if((type0 & Mem) != 0)
86: suffix = get_suffix(type0);
87:
88: /* fwait prefixed instructions */
89: if((t->base_opcode & 0xff00) == 0x9b00 &&
90: strcmp(suffix, "w") == 0)
91: continue;
92:
93: op0 = get_operand(type0);
94: for( ; *op0; op0++){
95: printf("\t%s%s\t%s\n", t->name, suffix, *op0);
96: }
97: }
98: }
99:
100: if(t->operands == 2){
101: for(i = 0; i < 32; i++){
102: type0 = 1 << i;
103: if((type0 & t->operand_types[0]) == 0)
104: continue;
105: for(j = 0; j < 32; j++){
106: type1 = 1 << j;
107: if((type1 & t->operand_types[1]) == 0)
108: continue;
109: if((type0 & Reg) != 0 && (type1 & Reg) != 0)
110: if(type0 != type1)
111: continue;
112:
113: suffix = "";
114: if((type0 & (Imm|Imm1)) != 0 && (type1 & Mem) != 0)
115: suffix = get_suffix(type0);
116: if((type0 & Mem) != 0 && (type1 & (Imm|Imm1)) != 0)
117: suffix = get_suffix(type1);
118:
119: op0 = get_operand(type0);
120: op1 = get_operand(type1);
121: for( ; *op0; op0++){
122: for( ; *op1; op1++){
123: printf("\t%s%s\t%s,%s\n", t->name, suffix,
124: *op0, *op1);
125: if(t->opcode_modifier & D){
126: printf("\t%s%s\t%s,%s\n", t->name, suffix,
127: *op1, *op0);
128: }
129: }
130: }
131: }
132: }
133: }
134: }
135: }
136:
137: static
138: char *
139: get_suffix(
140: unsigned long type)
141: {
142: switch(type){
143: case Imm8: return("b");
144: case Imm8S: return("b");
145: case Imm16: return("w");
146: case Imm32: return("l");
147: case Imm1: return("l"); /* all */
148: case Disp8: return("b");
149: case Disp16: return("w");
150: case Disp32: return("l");
151: case Mem8: return("b");
152: case Mem16: return("w");
153: case Mem32: return("l");
154: case BaseIndex: return("l"); /* all */
155: default: return("");
156: }
157: }
158:
159: static char *Reg8_table[] = { "%bl", NULL };
160: static char *Reg16_table[] = { "%bx", NULL };
161: static char *Reg32_table[] = { "%ebx", NULL };
162: static char *Imm8_table[] = { "$0x7f", NULL };
163: static char *Imm8S_table[] = { "$0xfe", NULL };
164: static char *Imm16_table[] = { "$0xface", NULL };
165: static char *Imm32_table[] = { "$0xcafebabe", NULL };
166: static char *Imm1_table[] = { "$0", "$1", NULL };
167: static char *Disp8_table[] = { "0x45", NULL };
168: static char *Disp16_table[] = { "0x7eed", NULL };
169: static char *Disp32_table[] = { "0xbabecafe", NULL };
170: static char *Mem8_table[] = { "0x88888888", NULL };
171: static char *Mem16_table[] = { "0x1616", NULL };
172: static char *Mem32_table[] = { "0x32323232", NULL };
173: static char *BaseIndex_table[] = { "0xdeadbeef(%ebx,%ecx,8)", NULL };
174: static char *InOutPortReg_table[] = { "%dx", NULL };
175: static char *ShiftCount_table[] = { "%cl", NULL };
176: static char *Control_table[] = { "%cr0", NULL };
177: static char *Debug_table[] = { "%db0", NULL };
178: static char *Test_table[] = { "%tr3", NULL };
179: static char *FloatReg_table[] = { "%st(1)", NULL };
180: static char *FloatAcc_table[] = { "%st", NULL };
181: static char *SReg2_table[] = { "%ds", NULL };
182: static char *SReg3_table[] = { "%fs", NULL };
183: static char *Acc_table[] = { "%eax", NULL };
184: static char *JumpAbsolute_table[] = { "*0xbadeface", NULL };
185: static char *Abs8_table[] = { "0xab", NULL };
186: static char *Abs16_table[] = { "0xabcd", NULL };
187: static char *Abs32_table[] = { "0xabcdef01", NULL };
188: static char *hosed_table[] = { "hosed", NULL };
189:
190: static
191: char **
192: get_operand(
193: unsigned long type)
194: {
195: switch(type){
196: case Reg8: return(Reg8_table);
197: case Reg16: return(Reg16_table);
198: case Reg32: return(Reg32_table);
199: case Imm8: return(Imm8_table);
200: case Imm8S: return(Imm8S_table);
201: case Imm16: return(Imm16_table);
202: case Imm32: return(Imm32_table);
203: case Imm1: return(Imm1_table);
204: case Disp8: return(Disp8_table);
205: case Disp16: return(Disp16_table);
206: case Disp32: return(Disp32_table);
207: case Mem8: return(Mem8_table);
208: case Mem16: return(Mem16_table);
209: case Mem32: return(Mem32_table);
210: case BaseIndex: return(BaseIndex_table);
211: case InOutPortReg: return(InOutPortReg_table);
212: case ShiftCount: return(ShiftCount_table);
213: case Control: return(Control_table);
214: case Debug: return(Debug_table);
215: case Test: return(Test_table);
216: case FloatReg: return(FloatReg_table);
217: case FloatAcc: return(FloatAcc_table);
218: case SReg2: return(SReg2_table);
219: case SReg3: return(SReg3_table);
220: case Acc: return(Acc_table);
221: case JumpAbsolute: return(JumpAbsolute_table);
222: case Abs8: return(Abs8_table);
223: case Abs16: return(Abs16_table);
224: case Abs32: return(Abs32_table);
225: default: return(hosed_table);
226: }
227: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.