annotate gen/d-asm-i386.h @ 234:9760f54af0b7 trunk

[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing. Did a few cleanups in inline asm code.
author lindquist
date Sun, 08 Jun 2008 08:03:19 +0200
parents 092468448d25
children fa691b1c0498
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1 // Taken from GDC source, GPL!
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
3 #include "dmd/id.h"
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
4
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
5 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
6 Reg_Invalid = -1,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
7 Reg_EAX = 0,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
8 Reg_EBX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
9 Reg_ECX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
10 Reg_EDX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
11 Reg_ESI,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
12 Reg_EDI,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
13 Reg_EBP,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
14 Reg_ESP,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
15 Reg_ST,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
16 Reg_ST1, Reg_ST2, Reg_ST3, Reg_ST4, Reg_ST5, Reg_ST6, Reg_ST7,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
17 Reg_MM0, Reg_MM1, Reg_MM2, Reg_MM3, Reg_MM4, Reg_MM5, Reg_MM6, Reg_MM7,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
18 Reg_XMM0, Reg_XMM1, Reg_XMM2, Reg_XMM3, Reg_XMM4, Reg_XMM5, Reg_XMM6, Reg_XMM7,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
19 // will need 64-bit rax,etc. eventually
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
20 // xmm8-15?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
21 Reg_EFLAGS,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
22 Reg_CS,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
23 Reg_DS,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
24 Reg_SS,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
25 Reg_ES,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
26 Reg_FS,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
27 Reg_GS,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
28 Reg_AX, Reg_BX, Reg_CX, Reg_DX, Reg_SI, Reg_DI, Reg_BP, Reg_SP,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
29 Reg_AL, Reg_AH, Reg_BL, Reg_BH, Reg_CL, Reg_CH, Reg_DL, Reg_DH,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
30 Reg_CR0, Reg_CR2, Reg_CR3, Reg_CR4,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
31 Reg_DR0, Reg_DR1, Reg_DR2, Reg_DR3, Reg_DR6, Reg_DR7,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
32 Reg_TR3, Reg_TR4, Reg_TR5, Reg_TR6, Reg_TR7
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
33 } Reg;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
34
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
35 static const int N_Regs = /*gp*/ 8 + /*fp*/ 8 + /*mmx*/ 8 + /*sse*/ 8 +
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
36 /*seg*/ 6 + /*16bit*/ 8 + /*8bit*/ 8 + /*sys*/ 4+6+5 + /*flags*/ + 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
37
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
38 #define NULL_TREE ""
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
39
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
40 static struct {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
41 const char * name;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
42 std::string gccName; // GAS will take upper case, but GCC won't (needed for the clobber list)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
43 Identifier * ident;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
44 char size;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
45 char baseReg; // %% todo: Reg, Reg_XX
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
46 } regInfo[N_Regs] = {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
47 { "EAX", NULL_TREE, NULL, 4, Reg_EAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
48 { "EBX", NULL_TREE, NULL, 4, Reg_EBX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
49 { "ECX", NULL_TREE, NULL, 4, Reg_ECX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
50 { "EDX", NULL_TREE, NULL, 4, Reg_EDX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
51 { "ESI", NULL_TREE, NULL, 4, Reg_ESI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
52 { "EDI", NULL_TREE, NULL, 4, Reg_EDI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
53 { "EBP", NULL_TREE, NULL, 4, Reg_EBP },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
54 { "ESP", NULL_TREE, NULL, 4, Reg_ESP },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
55 { "ST", NULL_TREE, NULL, 10, Reg_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
56 { "ST(1)", NULL_TREE, NULL,10, Reg_ST1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
57 { "ST(2)", NULL_TREE, NULL,10, Reg_ST2 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
58 { "ST(3)", NULL_TREE, NULL,10, Reg_ST3 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
59 { "ST(4)", NULL_TREE, NULL,10, Reg_ST4 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
60 { "ST(5)", NULL_TREE, NULL,10, Reg_ST5 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
61 { "ST(6)", NULL_TREE, NULL,10, Reg_ST6 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
62 { "ST(7)", NULL_TREE, NULL,10, Reg_ST7 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
63 { "MM0", NULL_TREE, NULL, 8, Reg_MM0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
64 { "MM1", NULL_TREE, NULL, 8, Reg_MM1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
65 { "MM2", NULL_TREE, NULL, 8, Reg_MM2 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
66 { "MM3", NULL_TREE, NULL, 8, Reg_MM3 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
67 { "MM4", NULL_TREE, NULL, 8, Reg_MM4 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
68 { "MM5", NULL_TREE, NULL, 8, Reg_MM5 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
69 { "MM6", NULL_TREE, NULL, 8, Reg_MM6 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
70 { "MM7", NULL_TREE, NULL, 8, Reg_MM7 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
71 { "XMM0", NULL_TREE, NULL, 16, Reg_XMM0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
72 { "XMM1", NULL_TREE, NULL, 16, Reg_XMM1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
73 { "XMM2", NULL_TREE, NULL, 16, Reg_XMM2 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
74 { "XMM3", NULL_TREE, NULL, 16, Reg_XMM3 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
75 { "XMM4", NULL_TREE, NULL, 16, Reg_XMM4 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
76 { "XMM5", NULL_TREE, NULL, 16, Reg_XMM5 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
77 { "XMM6", NULL_TREE, NULL, 16, Reg_XMM6 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
78 { "XMM7", NULL_TREE, NULL, 16, Reg_XMM7 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
79 { "FLAGS", NULL_TREE, NULL, 0, Reg_EFLAGS }, // the gcc name is "flags"; not used in assembler input
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
80 { "CS", NULL_TREE, NULL, 2, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
81 { "DS", NULL_TREE, NULL, 2, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
82 { "SS", NULL_TREE, NULL, 2, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
83 { "ES", NULL_TREE, NULL, 2, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
84 { "FS", NULL_TREE, NULL, 2, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
85 { "GS", NULL_TREE, NULL, 2, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
86 { "AX", NULL_TREE, NULL, 2, Reg_EAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
87 { "BX", NULL_TREE, NULL, 2, Reg_EBX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
88 { "CX", NULL_TREE, NULL, 2, Reg_ECX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
89 { "DX", NULL_TREE, NULL, 2, Reg_EDX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
90 { "SI", NULL_TREE, NULL, 2, Reg_ESI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
91 { "DI", NULL_TREE, NULL, 2, Reg_EDI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
92 { "BP", NULL_TREE, NULL, 2, Reg_EBP },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
93 { "SP", NULL_TREE, NULL, 2, Reg_ESP },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
94 { "AL", NULL_TREE, NULL, 1, Reg_EAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
95 { "AH", NULL_TREE, NULL, 1, Reg_EAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
96 { "BL", NULL_TREE, NULL, 1, Reg_EBX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
97 { "BH", NULL_TREE, NULL, 1, Reg_EBX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
98 { "CL", NULL_TREE, NULL, 1, Reg_ECX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
99 { "CH", NULL_TREE, NULL, 1, Reg_ECX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
100 { "DL", NULL_TREE, NULL, 1, Reg_EDX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
101 { "DH", NULL_TREE, NULL, 1, Reg_EDX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
102 { "CR0", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
103 { "CR2", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
104 { "CR3", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
105 { "CR4", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
106 { "DR0", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
107 { "DR1", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
108 { "DR2", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
109 { "DR3", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
110 { "DR6", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
111 { "DR7", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
112 { "TR3", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
113 { "TR4", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
114 { "TR5", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
115 { "TR6", NULL_TREE, NULL, 0, -1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
116 { "TR7", NULL_TREE, NULL, 0, -1 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
117 };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
118
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
119 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
120 No_Type_Needed,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
121 Int_Types,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
122 Word_Types, // same as Int_Types, but byte is not allowed
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
123 FP_Types,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
124 FPInt_Types,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
125 Byte_NoType, // byte only, but no type suffix
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
126 } TypeNeeded;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
127
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
128 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
129 No_Link,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
130 Out_Mnemonic,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
131 Next_Form
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
132 } OpLink;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
133
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
134 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
135 Clb_SizeAX = 0x01,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
136 Clb_SizeDXAX = 0x02,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
137 Clb_EAX = 0x03,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
138 Clb_DXAX_Mask = 0x03,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
139
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
140 Clb_Flags = 0x04,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
141 Clb_DI = 0x08,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
142 Clb_SI = 0x10,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
143 Clb_CX = 0x20,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
144 Clb_ST = 0x40,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
145 Clb_SP = 0x80 // Doesn't actually let GCC know the frame pointer is modified
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
146 } ImplicitClober;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
147
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
148 // "^ +/..\([A-Za-z_0-9]+\).*" -> " \1,"
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
149 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
150 Op_Invalid,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
151 Op_Adjust,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
152 Op_Dst,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
153 Op_Upd,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
154 Op_DstW,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
155 Op_DstF,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
156 Op_UpdF,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
157 Op_DstSrc,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
158 Op_DstSrcF,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
159 Op_UpdSrcF,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
160 Op_DstSrcFW,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
161 Op_UpdSrcFW,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
162 Op_DstSrcSSE,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
163 Op_DstSrcMMX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
164 Op_DstSrcImmS,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
165 Op_DstSrcImmM,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
166 Op_UpdSrcShft,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
167 Op_DstSrcNT,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
168 Op_UpdSrcNT,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
169 Op_DstMemNT,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
170 Op_DstRMBNT,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
171 Op_DstRMWNT,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
172 Op_UpdUpd,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
173 Op_UpdUpdF,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
174 Op_Src,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
175 Op_SrcRMWNT,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
176 Op_SrcW,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
177 Op_SrcImm,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
178 Op_Src_DXAXF,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
179 Op_SrcMemNT,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
180 Op_SrcMemNTF,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
181 Op_SrcSrc,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
182 Op_SrcSrcF,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
183 Op_SrcSrcFW,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
184 Op_SrcSrcSSEF,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
185 Op_SrcSrcMMX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
186 Op_Shift,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
187 Op_Branch,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
188 Op_CBranch,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
189 Op_0,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
190 Op_0_AX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
191 Op_0_DXAX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
192 Op_Loop,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
193 Op_Flags,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
194 Op_F0_ST,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
195 Op_F0_P,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
196 Op_Fs_P,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
197 Op_Fis,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
198 Op_Fis_ST,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
199 Op_Fis_P,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
200 Op_Fid,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
201 Op_Fid_P,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
202 Op_Ffd,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
203 Op_FfdR,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
204 Op_Ffd_P,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
205 Op_FfdR_P,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
206 Op_Fd_P,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
207 Op_FdST,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
208 Op_FMath,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
209 Op_FdSTiSTi,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
210 Op_FPMath,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
211 Op_FCmp,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
212 Op_FCmp1,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
213 Op_FCmpP,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
214 Op_FCmpP1,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
215 Op_FCmpFlg,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
216 Op_FCmpFlgP,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
217 Op_fld,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
218 Op_fldR,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
219 Op_fxch,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
220 Op_fxch1,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
221 Op_fxch0,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
222 Op_SizedStack,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
223 Op_bound,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
224 Op_bswap,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
225 Op_cmps,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
226 Op_cmpsd,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
227 Op_cmpsX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
228 Op_cmpxchg8b,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
229 Op_cmpxchg,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
230 Op_cpuid,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
231 Op_enter,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
232 Op_fdisi,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
233 Op_feni,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
234 Op_fsetpm,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
235 Op_fXstsw,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
236 Op_imul,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
237 Op_imul2,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
238 Op_imul1,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
239 Op_in,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
240 Op_ins,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
241 Op_insX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
242 Op_iret,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
243 Op_iretd,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
244 Op_lods,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
245 Op_lodsX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
246 Op_movs,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
247 Op_movsd,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
248 Op_movsX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
249 Op_movsx,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
250 Op_movzx,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
251 Op_mul,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
252 Op_out,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
253 Op_outs,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
254 Op_outsX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
255 Op_push,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
256 Op_ret,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
257 Op_retf,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
258 Op_scas,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
259 Op_scasX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
260 Op_stos,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
261 Op_stosX,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
262 Op_xlat,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
263 N_AsmOpInfo,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
264 Op_Align,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
265 Op_Even,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
266 Op_Naked,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
267 Op_db,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
268 Op_ds,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
269 Op_di,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
270 Op_dl,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
271 Op_df,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
272 Op_dd,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
273 Op_de
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
274 } AsmOp;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
275
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
276 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
277 Opr_None = 0,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
278 OprC_MRI = 1,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
279 OprC_MR = 2,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
280 OprC_Mem = 3,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
281 OprC_Reg = 4,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
282 OprC_Imm = 5,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
283 OprC_SSE = 6,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
284 OprC_SSE_Mem = 7,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
285 OprC_R32 = 8,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
286 OprC_RWord = 9,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
287 OprC_RFP = 10,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
288 OprC_AbsRel = 11,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
289 OprC_Relative = 12,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
290 OprC_Port = 13, // DX or imm
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
291 OprC_AX = 14, // AL,AX,EAX
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
292 OprC_DX = 15, // only DX
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
293 OprC_MMX = 16,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
294 OprC_MMX_Mem = 17,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
295 OprC_Shift = 18, // imm or CL
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
296
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
297 Opr_ClassMask = 0x1f,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
298
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
299 Opr_Dest = 0x20,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
300 Opr_Update = 0x60,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
301
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
302 Opr_NoType = 0x80,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
303 } OprVals;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
304
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
305
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
306 typedef struct {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
307 } AsmOprInfo;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
308
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
309 typedef unsigned char Opr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
310
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
311 typedef struct {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
312 Opr operands[3];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
313 unsigned char
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
314 needsType : 3,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
315 implicitClobbers : 8,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
316 linkType : 2;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
317 unsigned link;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
318
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
319 /*
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
320 bool takesLabel() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
321 return operands[0] & Opr_Label;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
322 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
323 */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
324
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
325 unsigned nOperands() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
326 if (!operands[0])
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
327 return 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
328 else if (!operands[1])
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
329 return 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
330 else if (!operands[2])
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
331 return 2;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
332 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
333 return 3;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
334 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
335 } AsmOpInfo;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
336
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
337 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
338 Mn_fdisi,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
339 Mn_feni,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
340 Mn_fsetpm,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
341 Mn_iretw,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
342 Mn_iret,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
343 Mn_lret,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
344 Mn_cmpxchg8b,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
345 N_AltMn
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
346 } Alternate_Mnemonics;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
347
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
348 static const char * alternateMnemonics[N_AltMn] = {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
349 ".byte 0xdb, 0xe1",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
350 ".byte 0xdb, 0xe0",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
351 ".byte 0xdb, 0xe4",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
352 "iretw",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
353 "iret",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
354 "lret",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
355 "cmpxchg8b" };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
356
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
357 #define mri OprC_MRI
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
358 #define mr OprC_MR
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
359 #define mem OprC_Mem
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
360 // for now mfp=mem
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
361 #define mfp OprC_Mem
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
362 #define reg OprC_Reg
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
363 #define imm OprC_Imm
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
364 #define sse OprC_SSE
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
365 #define ssem OprC_SSE_Mem
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
366 #define mmx OprC_MMX
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
367 #define mmxm OprC_MMX_Mem
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
368 #define r32 OprC_R32
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
369 #define rw OprC_RWord
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
370 #define rfp OprC_RFP
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
371 #define port OprC_Port
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
372 #define ax OprC_AX
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
373 #define dx OprC_DX
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
374 #define shft OprC_Shift
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
375 #define D Opr_Dest
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
376 #define U Opr_Update
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
377 #define N Opr_NoType
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
378 //#define L Opr_Label
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
379
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
380 // D=dest, N=notype
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
381 static AsmOpInfo asmOpInfo[N_AsmOpInfo] = {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
382 /* Op_Invalid */ {},
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
383 /* Op_Adjust */ { 0,0,0, 0, Clb_EAX /*just AX*/ },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
384 /* Op_Dst */ { D|mr, 0, 0, 1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
385 /* Op_Upd */ { U|mr, 0, 0, 1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
386 /* Op_DstW */ { D|mr, 0, 0, Word_Types },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
387 /* Op_DstF */ { D|mr, 0, 0, 1, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
388 /* Op_UpdF */ { U|mr, 0, 0, 1, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
389 /* Op_DstSrc */ { D|mr, mri, 0,/**/1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
390 /* Op_DstSrcF */ { D|mr, mri, 0,/**/1, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
391 /* Op_UpdSrcF */ { U|mr, mri, 0,/**/1, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
392 /* Op_DstSrcFW */ { D|mr, mri, 0,/**/Word_Types, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
393 /* Op_UpdSrcFW */ { U|mr, mri, 0,/**/Word_Types, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
394 /* Op_DstSrcSSE */ { U|sse, ssem, 0 }, // some may not be update %%
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
395 /* Op_DstSrcMMX */ { U|mmx, mmxm, 0 }, // some may not be update %%
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
396 /* Op_DstSrcImmS*/ { U|sse, ssem, N|imm }, // some may not be update %%
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
397 /* Op_DstSrcImmM*/ { U|mmx, mmxm, N|imm }, // some may not be update %%
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
398 /* Op_UpdSrcShft*/ { U|mr, reg, N|shft, 1, Clb_Flags }, // 16/32 only
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
399 /* Op_DstSrcNT */ { D|mr, mr, 0, 0 }, // used for movd .. operands can be rm32,sse,mmx
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
400 /* Op_UpdSrcNT */ { U|mr, mr, 0, 0 }, // used for movd .. operands can be rm32,sse,mmx
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
401 /* Op_DstMemNT */ { D|mem, 0, 0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
402 /* Op_DstRMBNT */ { D|mr, 0, 0, Byte_NoType },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
403 /* Op_DstRMWNT */ { D|mr, 0, 0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
404 /* Op_UpdUpd */ { U|mr,U|mr, 0,/**/1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
405 /* Op_UpdUpdF */ { U|mr,U|mr, 0,/**/1, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
406 /* Op_Src */ { mri, 0, 0, 1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
407 /* Op_SrcRMWNT */ { mr, 0, 0, 0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
408 /* Op_SrcW */ { mri, 0, 0, Word_Types },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
409 /* Op_SrcImm */ { imm },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
410 /* Op_Src_DXAXF */ { mr, 0, 0, 1, Clb_SizeDXAX|Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
411 /* Op_SrcMemNT */ { mem, 0, 0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
412 /* Op_SrcMemNTF */ { mem, 0, 0, 0, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
413 /* Op_SrcSrc */ { mr, mri, 0, 1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
414 /* Op_SrcSrcF */ { mr, mri, 0, 1, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
415 /* Op_SrcSrcFW */ { mr, mri, 0, Word_Types, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
416 /* Op_SrcSrcSSEF*/ { sse, ssem, 0, 0, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
417 /* Op_SrcSrcMMX */ { mmx, mmx, 0, },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
418 /* Op_Shift */ { D|mr,N|shft, 0,/**/1, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
419 /* Op_Branch */ { mri },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
420 /* Op_CBranch */ { imm },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
421 /* Op_0 */ { 0,0,0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
422 /* Op_0_AX */ { 0,0,0, 0, Clb_SizeAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
423 /* Op_0_DXAX */ { 0,0,0, 0, Clb_SizeDXAX }, // but for cwd/cdq -- how do know the size..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
424 /* Op_Loop */ { imm, 0, 0, 0, Clb_CX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
425 /* Op_Flags */ { 0,0,0, 0, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
426 /* Op_F0_ST */ { 0,0,0, 0, Clb_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
427 /* Op_F0_P */ { 0,0,0, 0, Clb_ST }, // push, pops, etc. not sure how to inform gcc..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
428 /* Op_Fs_P */ { mem, 0, 0, 0, Clb_ST }, // "
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
429 /* Op_Fis */ { mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
430 /* Op_Fis_ST */ { mem, 0, 0, FPInt_Types, Clb_ST }, // "
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
431 /* Op_Fis_P */ { mem, 0, 0, FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
432 /* Op_Fid */ { D|mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
433 /* Op_Fid_P */ { D|mem, 0, 0, FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
434 /* Op_Ffd */ { D|mfp, 0, 0, FP_Types, 0, Next_Form, Op_FfdR }, // only 16bit and 32bit, DMD defaults to 16bit, reg form doesn't need type
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
435 /* Op_FfdR */ { D|rfp, 0, 0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
436 /* Op_Ffd_P */ { D|mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FfdR_P, }, // pop, fld so also 80 bit, "
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
437 /* Op_FfdR_P */ { D|rfp, 0, 0, 0, Clb_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
438 /* Op_Fd_P */ { D|mem, 0, 0, 0, Clb_ST }, // "
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
439 /* Op_FdST */ { D|rfp, 0, 0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
440 /* Op_FMath */ { mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FdSTiSTi }, // and only single or double prec
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
441 /* Op_FdSTiSTi */ { D|rfp, rfp, 0, },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
442 /* Op_FPMath */ { D|rfp, rfp, 0, 0, Clb_ST, Next_Form, Op_F0_P }, // pops
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
443 /* Op_FCmp */ { mfp, 0, 0, FP_Types, 0, Next_Form, Op_FCmp1 }, // DMD defaults to float ptr
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
444 /* Op_FCmp1 */ { rfp, 0, 0, 0, 0, Next_Form, Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
445 /* Op_FCmpP */ { mfp, 0, 0, FP_Types, 0, Next_Form, Op_FCmpP1 }, // pops
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
446 /* Op_FCmpP1 */ { rfp, 0, 0, 0, 0, Next_Form, Op_F0_P }, // pops
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
447 /* Op_FCmpFlg */ { rfp, rfp, 0, 0, Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
448 /* Op_FCmpFlgP */ { rfp, rfp, 0, 0, Clb_Flags }, // pops
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
449 /* Op_fld */ { mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_fldR },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
450 /* Op_fldR */ { rfp, 0, 0, 0, Clb_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
451 /* Op_fxch */ { D|rfp,D|rfp, 0, 0, Clb_ST, Next_Form, Op_fxch1 }, // not in intel manual?, but DMD allows it (gas won't), second arg must be ST
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
452 /* Op_fxch1 */ { D|rfp, 0, 0, 0, Clb_ST, Next_Form, Op_fxch0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
453 /* Op_fxch0 */ { 0, 0, 0, 0, Clb_ST }, // Also clobbers ST(1)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
454 /* Op_SizedStack*/ { 0, 0, 0, 0, Clb_SP }, // type suffix special case
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
455 /* Op_bound */ { mr, mri, 0, Word_Types }, // operands *not* reversed for gas
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
456 /* Op_bswap */ { D|r32 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
457 /* Op_cmps */ { mem, mem, 0, 1, Clb_DI|Clb_SI|Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
458 /* Op_cmpsd */ { 0, 0, 0, 0, Clb_DI|Clb_SI|Clb_Flags, Next_Form, Op_DstSrcImmS },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
459 /* Op_cmpsX */ { 0, 0, 0, 0, Clb_DI|Clb_SI|Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
460 /* Op_cmpxchg8b */ { D|mem/*64*/,0,0, 0, Clb_SizeDXAX/*32*/|Clb_Flags, Out_Mnemonic, Mn_cmpxchg8b },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
461 /* Op_cmpxchg */ { D|mr, reg, 0, 1, Clb_SizeAX|Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
462 /* Op_cpuid */ { 0,0,0 }, // Clobbers eax, ebx, ecx, and edx. Handled specially below.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
463 /* Op_enter */ { imm, imm }, // operands *not* reversed for gas, %% inform gcc of EBP clobber?,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
464 /* Op_fdisi */ { 0,0,0, 0, 0, Out_Mnemonic, Mn_fdisi },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
465 /* Op_feni */ { 0,0,0, 0, 0, Out_Mnemonic, Mn_feni },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
466 /* Op_fsetpm */ { 0,0,0, 0, 0, Out_Mnemonic, Mn_fsetpm },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
467 /* Op_fXstsw */ { D|mr, 0, 0, }, // ax is the only allowed register
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
468 /* Op_imul */ { D|reg, mr, imm, 1, Clb_Flags, Next_Form, Op_imul2 }, // 16/32 only
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
469 /* Op_imul2 */ { D|reg, mri, 0, 1, Clb_Flags, Next_Form, Op_imul1 }, // 16/32 only
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
470 /* Op_imul1 */ { mr, 0, 0, 1, Clb_Flags|Clb_SizeDXAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
471 /* Op_in */ { D|ax,N|port,0, 1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
472 /* Op_ins */ { mem,N|dx, 0, 1, Clb_DI }, // can't override ES segment for this one
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
473 /* Op_insX */ { 0, 0, 0, 0, Clb_DI }, // output segment overrides %% needs work
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
474 /* Op_iret */ { 0,0,0, 0, 0, Out_Mnemonic, Mn_iretw },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
475 /* Op_iretd */ { 0,0,0, 0, 0, Out_Mnemonic, Mn_iret },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
476 /* Op_lods */ { mem, 0, 0, 1, Clb_SI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
477 /* Op_lodsX */ { 0, 0, 0, 0, Clb_SI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
478 /* Op_movs */ { mem, mem, 0, 1, Clb_DI|Clb_SI }, // only src/DS can be overridden
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
479 /* Op_movsd */ { 0, 0, 0, 0, Clb_DI|Clb_SI, Next_Form, Op_DstSrcSSE }, // %% gas doesn't accept movsd .. has to movsl
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
480 /* Op_movsX */ { 0, 0, 0, 0, Clb_DI|Clb_SI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
481 /* Op_movsx */ { D|reg, mr, 0, 1 }, // type suffix is special case
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
482 /* Op_movzx */ { D|reg, mr, 0, 1 }, // type suffix is special case
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
483 /* Op_mul */ { U|ax, mr, 0, 1, Clb_SizeDXAX|Clb_Flags, Next_Form, Op_Src_DXAXF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
484 /* Op_out */ { N|port,ax, 0, 1 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
485 /* Op_outs */ { N|dx, mem, 0, 1, Clb_SI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
486 /* Op_outsX */ { 0, 0, 0, 0, Clb_SI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
487 /* Op_push */ { mri, 0, 0, Word_Types, Clb_SP }, // would be Op_SrcW, but DMD defaults to 32-bit for immediate form
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
488 /* Op_ret */ { imm, 0, 0, 0, 0, Next_Form, Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
489 /* Op_retf */ { 0, 0, 0, 0, 0, Out_Mnemonic, Mn_lret },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
490 /* Op_scas */ { mem, 0, 0, 1, Clb_DI|Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
491 /* Op_scasX */ { 0, 0, 0, 0, Clb_DI|Clb_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
492 /* Op_stos */ { mem, 0, 0, 1, Clb_DI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
493 /* Op_stosX */ { 0, 0, 0, 0, Clb_DI },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
494 /* Op_xlat */ { mem, 0, 0, 0, Clb_SizeAX }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
495
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
496 /// * Op_arpl */ { D|mr, reg }, // 16 only -> DstSrc
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
497 /// * Op_bsX */ { rw, mrw, 0, 1, Clb_Flags },//->srcsrcf
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
498 /// * Op_bt */ { mrw, riw, 0, 1, Clb_Flags },//->srcsrcf
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
499 /// * Op_btX */ { D|mrw, riw, 0, 1, Clb_Flags },//->dstsrcf .. immediate does not contribute to size
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
500 /// * Op_cmovCC */ { D|rw, mrw, 0, 1 } // ->dstsrc
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
501 };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
502
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
503 #undef mri
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
504 #undef mr
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
505 #undef mem
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
506 #undef mfp
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
507 #undef reg
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
508 #undef imm
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
509 #undef sse
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
510 #undef ssem
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
511 #undef mmx
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
512 #undef mmxm
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
513 #undef r32
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
514 #undef rw
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
515 #undef rfp
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
516 #undef port
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
517 #undef ax
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
518 #undef dx
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
519 #undef shft
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
520 #undef D
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
521 #undef U
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
522 #undef N
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
523 //#undef L
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
524
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
525 typedef struct {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
526 const char * inMnemonic;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
527 AsmOp asmOp;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
528 } AsmOpEnt;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
529
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
530 /* Some opcodes which have data size restrictions, but we don't check
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
531
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
532 cmov, l<segreg> ?, lea, lsl, shld
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
533
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
534 todo: push <immediate> is always the 32-bit form, even tho push <mem> is 16-bit
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
535 */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
536
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
537 static AsmOpEnt opData[] = {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
538 { "aaa", Op_Adjust },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
539 { "aad", Op_Adjust },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
540 { "aam", Op_Adjust },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
541 { "aas", Op_Adjust },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
542 { "adc", Op_UpdSrcF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
543 { "add", Op_UpdSrcF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
544 { "addpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
545 { "addps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
546 { "addsd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
547 { "addss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
548 { "addsubpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
549 { "addsubps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
550 { "align", Op_Align },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
551 { "and", Op_UpdSrcF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
552 { "andnpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
553 { "andnps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
554 { "andpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
555 { "andps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
556 { "arpl", Op_UpdSrcNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
557 { "bound", Op_bound },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
558 { "bsf", Op_SrcSrcFW },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
559 { "bsr", Op_SrcSrcFW },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
560 { "bswap", Op_bswap },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
561 { "bt", Op_SrcSrcFW },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
562 { "btc", Op_UpdSrcFW },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
563 { "btr", Op_UpdSrcFW },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
564 { "bts", Op_UpdSrcFW },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
565 { "call", Op_Branch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
566 { "cbw", Op_0_AX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
567 { "cdq", Op_0_DXAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
568 { "clc", Op_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
569 { "cld", Op_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
570 { "clflush",Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
571 { "cli", Op_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
572 { "clts", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
573 { "cmc", Op_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
574 { "cmova", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
575 { "cmovae", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
576 { "cmovb", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
577 { "cmovbe", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
578 { "cmovc", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
579 { "cmove", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
580 { "cmovg", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
581 { "cmovge", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
582 { "cmovl", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
583 { "cmovle", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
584 { "cmovna", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
585 { "cmovnae",Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
586 { "cmovnb", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
587 { "cmovnbe",Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
588 { "cmovnc", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
589 { "cmovne", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
590 { "cmovng", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
591 { "cmovnge",Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
592 { "cmovnl", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
593 { "cmovnle",Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
594 { "cmovno", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
595 { "cmovnp", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
596 { "cmovns", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
597 { "cmovnz", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
598 { "cmovo", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
599 { "cmovp", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
600 { "cmovpe", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
601 { "cmovpo", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
602 { "cmovs", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
603 { "cmovz", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
604 { "cmp", Op_SrcSrcF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
605 { "cmppd", Op_DstSrcImmS },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
606 { "cmpps", Op_DstSrcImmS },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
607 { "cmps", Op_cmps },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
608 { "cmpsb", Op_cmpsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
609 { "cmpsd", Op_cmpsd }, // string cmp, and SSE cmp
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
610 { "cmpss", Op_DstSrcImmS },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
611 { "cmpsw", Op_cmpsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
612 { "cmpxch8b", Op_cmpxchg8b }, // %% DMD opcode typo?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
613 { "cmpxchg", Op_cmpxchg },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
614 { "comisd", Op_SrcSrcSSEF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
615 { "comiss", Op_SrcSrcSSEF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
616 { "cpuid", Op_cpuid },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
617 { "cvtdq2pd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
618 { "cvtdq2ps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
619 { "cvtpd2dq", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
620 { "cvtpd2pi", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
621 { "cvtpd2ps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
622 { "cvtpi2pd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
623 { "cvtpi2ps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
624 { "cvtps2dq", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
625 { "cvtps2pd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
626 { "cvtps2pi", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
627 { "cvtsd2si", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
628 { "cvtsd2ss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
629 { "cvtsi2sd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
630 { "cvtsi2ss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
631 { "cvtss2sd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
632 { "cvtss2si", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
633 { "cvttpd2dq", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
634 { "cvttpd2pi", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
635 { "cvttps2dq", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
636 { "cvttps2pi", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
637 { "cvttsd2si", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
638 { "cvttss2si", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
639 { "cwd", Op_0_DXAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
640 { "cwde", Op_0_AX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
641 //{ "da", Op_ },// dunno what this is -- takes labels?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
642 { "daa", Op_Adjust },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
643 { "das", Op_Adjust },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
644 { "db", Op_db },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
645 { "dd", Op_dd },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
646 { "de", Op_de },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
647 { "dec", Op_UpdF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
648 { "df", Op_df },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
649 { "di", Op_di },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
650 { "div", Op_Src_DXAXF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
651 { "divpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
652 { "divps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
653 { "divsd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
654 { "divss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
655 { "dl", Op_dl },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
656 { "dq", Op_dl },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
657 { "ds", Op_ds },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
658 { "dt", Op_de },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
659 { "dw", Op_ds },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
660 { "emms", Op_0 }, // clobber all mmx/fp?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
661 { "enter", Op_enter },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
662 { "even", Op_Even },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
663 { "f2xm1", Op_F0_ST }, // %% most of these are update...
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
664 { "fabs", Op_F0_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
665 { "fadd", Op_FMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
666 { "faddp", Op_FPMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
667 { "fbld", Op_Fs_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
668 { "fbstp", Op_Fd_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
669 { "fchs", Op_F0_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
670 { "fclex", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
671 { "fcmovb", Op_FdSTiSTi }, // but only ST(0) can be the destination -- should be FdST0STi
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
672 { "fcmovbe", Op_FdSTiSTi },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
673 { "fcmove", Op_FdSTiSTi },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
674 { "fcmovnb", Op_FdSTiSTi },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
675 { "fcmovnbe", Op_FdSTiSTi },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
676 { "fcmovne", Op_FdSTiSTi },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
677 { "fcmovnu", Op_FdSTiSTi },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
678 { "fcmovu", Op_FdSTiSTi },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
679 { "fcom", Op_FCmp },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
680 { "fcomi", Op_FCmpFlg },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
681 { "fcomip", Op_FCmpFlgP },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
682 { "fcomp", Op_FCmpP },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
683 { "fcompp", Op_F0_P }, // pops twice
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
684 { "fcos", Op_F0_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
685 { "fdecstp",Op_F0_P }, // changes stack
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
686 { "fdisi", Op_fdisi },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
687 { "fdiv", Op_FMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
688 { "fdivp", Op_FPMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
689 { "fdivr", Op_FMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
690 { "fdivrp", Op_FPMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
691 { "feni", Op_feni },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
692 { "ffree", Op_FdST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
693 { "fiadd", Op_Fis_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
694 { "ficom", Op_Fis },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
695 { "ficomp", Op_Fis_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
696 { "fidiv", Op_Fis_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
697 { "fidivr", Op_Fis_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
698 { "fild", Op_Fis_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
699 { "fimul", Op_Fis_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
700 { "fincstp",Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
701 { "finit", Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
702 { "fist", Op_Fid }, // only 16,32bit
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
703 { "fistp", Op_Fid_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
704 { "fisttp", Op_Fid_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
705 { "fisub", Op_Fis_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
706 { "fisubr", Op_Fis_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
707 { "fld", Op_fld },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
708 { "fld1", Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
709 { "fldcw", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
710 { "fldenv", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
711 { "fldl2e", Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
712 { "fldl2t", Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
713 { "fldlg2", Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
714 { "fldln2", Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
715 { "fldpi", Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
716 { "fldz", Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
717 { "fmul", Op_FMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
718 { "fmulp", Op_FPMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
719 { "fnclex", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
720 { "fndisi", Op_fdisi }, // ??
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
721 { "fneni", Op_feni }, // ??
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
722 { "fninit", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
723 { "fnop", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
724 { "fnsave", Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
725 { "fnstcw", Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
726 { "fnstenv",Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
727 { "fnstsw", Op_fXstsw },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
728 { "fpatan", Op_F0_P }, // pop and modify new ST
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
729 { "fprem", Op_F0_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
730 { "fprem1", Op_F0_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
731 { "fptan", Op_F0_P }, // modify ST and push 1.0
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
732 { "frndint",Op_F0_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
733 { "frstor", Op_SrcMemNT }, // but clobbers everything
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
734 { "fsave", Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
735 { "fscale", Op_F0_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
736 { "fsetpm", Op_fsetpm },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
737 { "fsin", Op_F0_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
738 { "fsincos",Op_F0_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
739 { "fsqrt", Op_F0_ST },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
740 { "fst", Op_Ffd },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
741 { "fstcw", Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
742 { "fstenv", Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
743 { "fstp", Op_Ffd_P },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
744 { "fstsw", Op_fXstsw },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
745 { "fsub", Op_FMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
746 { "fsubp", Op_FPMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
747 { "fsubr", Op_FMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
748 { "fsubrp", Op_FPMath },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
749 { "ftst", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
750 { "fucom", Op_FCmp },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
751 { "fucomi", Op_FCmpFlg },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
752 { "fucomip",Op_FCmpFlgP },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
753 { "fucomp", Op_FCmpP },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
754 { "fucompp",Op_F0_P }, // pops twice
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
755 { "fwait", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
756 { "fxam", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
757 { "fxch", Op_fxch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
758 { "fxrstor",Op_SrcMemNT }, // clobbers FP,MMX,SSE
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
759 { "fxsave", Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
760 { "fxtract",Op_F0_P }, // pushes
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
761 { "fyl2x", Op_F0_P }, // pops
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
762 { "fyl2xp1",Op_F0_P }, // pops
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
763 { "haddpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
764 { "haddps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
765 { "hlt", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
766 { "hsubpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
767 { "hsubps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
768 { "idiv", Op_Src_DXAXF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
769 { "imul", Op_imul },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
770 { "in", Op_in },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
771 { "inc", Op_UpdF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
772 { "ins", Op_ins },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
773 { "insb", Op_insX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
774 { "insd", Op_insX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
775 { "insw", Op_insX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
776 { "int", Op_SrcImm },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
777 { "into", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
778 { "invd", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
779 { "invlpg", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
780 { "iret", Op_iret },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
781 { "iretd", Op_iretd },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
782 { "ja", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
783 { "jae", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
784 { "jb", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
785 { "jbe", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
786 { "jc", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
787 { "jcxz", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
788 { "je", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
789 { "jecxz", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
790 { "jg", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
791 { "jge", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
792 { "jl", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
793 { "jle", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
794 { "jmp", Op_Branch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
795 { "jna", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
796 { "jnae", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
797 { "jnb", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
798 { "jnbe", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
799 { "jnc", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
800 { "jne", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
801 { "jng", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
802 { "jnge", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
803 { "jnl", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
804 { "jnle", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
805 { "jno", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
806 { "jnp", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
807 { "jns", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
808 { "jnz", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
809 { "jo", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
810 { "jp", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
811 { "jpe", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
812 { "jpo", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
813 { "js", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
814 { "jz", Op_CBranch },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
815 { "lahf", Op_0_AX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
816 { "lar", Op_DstSrcFW }, // reg dest only
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
817 { "lddqu", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
818 { "ldmxcsr", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
819 { "lds", Op_DstSrc }, // reg dest only
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
820 { "lea", Op_DstSrc }, // "
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
821 { "leave", Op_0 }, // EBP,ESP clobbers
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
822 { "les", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
823 { "lfence",Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
824 { "lfs", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
825 { "lgdt", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
826 { "lgs", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
827 { "lidt", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
828 { "lldt", Op_SrcRMWNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
829 { "lmsw", Op_SrcRMWNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
830 { "lock", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
831 { "lods", Op_lods },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
832 { "lodsb", Op_lodsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
833 { "lodsd", Op_lodsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
834 { "lodsw", Op_lodsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
835 { "loop", Op_Loop },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
836 { "loope", Op_Loop },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
837 { "loopne",Op_Loop },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
838 { "loopnz",Op_Loop },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
839 { "loopz", Op_Loop },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
840 { "lsl", Op_DstSrcFW }, // reg dest only
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
841 { "lss", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
842 { "ltr", Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
843 { "maskmovdqu", Op_SrcSrcMMX }, // writes to [edi]
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
844 { "maskmovq", Op_SrcSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
845 { "maxpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
846 { "maxps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
847 { "maxsd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
848 { "maxss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
849 { "mfence",Op_0},
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
850 { "minpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
851 { "minps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
852 { "minsd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
853 { "minss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
854 { "monitor", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
855 { "mov", Op_DstSrc },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
856 { "movapd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
857 { "movaps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
858 { "movd", Op_DstSrcNT }, // also mmx and sse
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
859 { "movddup", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
860 { "movdq2q", Op_DstSrcNT }, // mmx/sse
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
861 { "movdqa", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
862 { "movdqu", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
863 { "movhlps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
864 { "movhpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
865 { "movhps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
866 { "movlhps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
867 { "movlpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
868 { "movlps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
869 { "movmskpd",Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
870 { "movmskps",Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
871 { "movntdq", Op_DstSrcNT }, // limited to sse, but mem dest
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
872 { "movnti", Op_DstSrcNT }, // limited to gpr, but mem dest
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
873 { "movntpd", Op_DstSrcNT }, // limited to sse, but mem dest
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
874 { "movntps", Op_DstSrcNT }, // limited to sse, but mem dest
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
875 { "movntq", Op_DstSrcNT }, // limited to mmx, but mem dest
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
876 { "movq", Op_DstSrcNT }, // limited to sse and mmx
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
877 { "movq2dq", Op_DstSrcNT }, // limited to sse <- mmx regs
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
878 { "movs", Op_movs },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
879 { "movsb", Op_movsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
880 { "movsd", Op_movsd },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
881 { "movshdup", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
882 { "movsldup", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
883 { "movss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
884 { "movsw", Op_movsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
885 { "movsx", Op_movsx }, // word-only, reg dest
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
886 { "movupd",Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
887 { "movups",Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
888 { "movzx", Op_movzx },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
889 { "mul", Op_mul },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
890 { "mulpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
891 { "mulps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
892 { "mulsd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
893 { "mulss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
894 { "mwait", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
895 { "naked", Op_Naked },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
896 { "neg", Op_UpdF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
897 { "nop", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
898 { "not", Op_Upd },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
899 { "or", Op_UpdSrcF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
900 { "orpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
901 { "orps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
902 { "out", Op_out },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
903 { "outs", Op_outs },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
904 { "outsb", Op_outsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
905 { "outsd", Op_outsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
906 { "outsw", Op_outsX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
907 { "packssdw", Op_DstSrcMMX }, // %% also SSE
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
908 { "packsswb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
909 { "packuswb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
910 { "paddb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
911 { "paddd", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
912 { "paddq", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
913 { "paddsb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
914 { "paddsw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
915 { "paddusb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
916 { "paddusw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
917 { "paddw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
918 { "pand", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
919 { "pandn", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
920 { "pavgb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
921 { "pavgw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
922 { "pcmpeqb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
923 { "pcmpeqd", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
924 { "pcmpeqw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
925 { "pcmpgtb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
926 { "pcmpgtd", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
927 { "pcmpgtw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
928 { "pextrw", Op_DstSrcImmM }, // gpr32 dest
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
929 { "pinsrw", Op_DstSrcImmM }, // gpr32(16), mem16 src, sse too
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
930 { "pmaddwd", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
931 { "pmaxsw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
932 { "pmaxub", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
933 { "pminsw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
934 { "pminub", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
935 { "pmovmskb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
936 { "pmulhuw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
937 { "pmulhw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
938 { "pmullw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
939 { "pmuludq", Op_DstSrcMMX }, // also sse
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
940 { "pop", Op_DstW },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
941 { "popa", Op_SizedStack }, // For intel this is always 16-bit
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
942 { "popad", Op_SizedStack }, // GAS doesn't accept 'popad' -- these clobber everything, but supposedly it would be used to preserve clobbered regs
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
943 { "popf", Op_SizedStack }, // rewrite the insn with a special case
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
944 { "popfd", Op_SizedStack },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
945 { "por", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
946 { "prefetchnta", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
947 { "prefetcht0", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
948 { "prefetcht1", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
949 { "prefetcht2", Op_SrcMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
950 { "psadbw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
951 { "pshufd", Op_DstSrcImmM },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
952 { "pshufhw", Op_DstSrcImmM },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
953 { "pshuflw", Op_DstSrcImmM },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
954 { "pshufw", Op_DstSrcImmM },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
955 { "pslld", Op_DstSrcMMX }, // immediate operands...
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
956 { "pslldq", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
957 { "psllq", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
958 { "psllw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
959 { "psrad", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
960 { "psraw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
961 { "psrld", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
962 { "psrldq", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
963 { "psrlq", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
964 { "psrlw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
965 { "psubb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
966 { "psubd", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
967 { "psubq", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
968 { "psubsb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
969 { "psubsw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
970 { "psubusb", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
971 { "psubusw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
972 { "psubw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
973 { "punpckhbw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
974 { "punpckhdq", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
975 { "punpckhqdq",Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
976 { "punpckhwd", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
977 { "punpcklbw", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
978 { "punpckldq", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
979 { "punpcklqdq",Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
980 { "punpcklwd", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
981 { "push", Op_push },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
982 { "pusha", Op_SizedStack },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
983 { "pushad", Op_SizedStack },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
984 { "pushf", Op_SizedStack },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
985 { "pushfd", Op_SizedStack },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
986 { "pxor", Op_DstSrcMMX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
987 { "rcl", Op_Shift }, // limited src operands -- change to shift
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
988 { "rcpps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
989 { "rcpss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
990 { "rcr", Op_Shift },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
991 { "rdmsr", Op_0_DXAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
992 { "rdpmc", Op_0_DXAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
993 { "rdtsc", Op_0_DXAX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
994 { "rep", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
995 { "repe", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
996 { "repne", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
997 { "repnz", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
998 { "repz", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
999 { "ret", Op_ret },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1000 { "retf", Op_retf },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1001 { "rol", Op_Shift },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1002 { "ror", Op_Shift },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1003 { "rsm", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1004 { "rsqrtps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1005 { "rsqrtss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1006 { "sahf", Op_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1007 { "sal", Op_Shift },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1008 { "sar", Op_Shift },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1009 { "sbb", Op_UpdSrcF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1010 { "scas", Op_scas },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1011 { "scasb", Op_scasX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1012 { "scasd", Op_scasX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1013 { "scasw", Op_scasX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1014 { "seta", Op_DstRMBNT }, // also gpr8
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1015 { "setae", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1016 { "setb", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1017 { "setbe", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1018 { "setc", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1019 { "sete", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1020 { "setg", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1021 { "setge", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1022 { "setl", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1023 { "setle", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1024 { "setna", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1025 { "setnae", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1026 { "setnb", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1027 { "setnbe", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1028 { "setnc", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1029 { "setne", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1030 { "setng", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1031 { "setnge", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1032 { "setnl", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1033 { "setnle", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1034 { "setno", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1035 { "setnp", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1036 { "setns", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1037 { "setnz", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1038 { "seto", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1039 { "setp", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1040 { "setpe", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1041 { "setpo", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1042 { "sets", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1043 { "setz", Op_DstRMBNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1044 { "sfence", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1045 { "sgdt", Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1046 { "shl", Op_Shift },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1047 { "shld", Op_UpdSrcShft },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1048 { "shr", Op_Shift },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1049 { "shrd", Op_UpdSrcShft },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1050 { "shufpd", Op_DstSrcImmS },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1051 { "shufps", Op_DstSrcImmS },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1052 { "sidt", Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1053 { "sldt", Op_DstRMWNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1054 { "smsw", Op_DstRMWNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1055 { "sqrtpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1056 { "sqrtps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1057 { "sqrtsd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1058 { "sqrtss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1059 { "stc", Op_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1060 { "std", Op_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1061 { "sti", Op_Flags },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1062 { "stmxcsr",Op_DstMemNT },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1063 { "stos", Op_stos },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1064 { "stosb", Op_stosX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1065 { "stosd", Op_stosX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1066 { "stosw", Op_stosX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1067 { "str", Op_DstMemNT }, // also r16
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1068 { "sub", Op_UpdSrcF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1069 { "subpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1070 { "subps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1071 { "subsd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1072 { "subss", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1073 { "sysenter",Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1074 { "sysexit", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1075 { "test", Op_SrcSrcF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1076 { "ucomisd", Op_SrcSrcSSEF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1077 { "ucomiss", Op_SrcSrcSSEF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1078 { "ud2", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1079 { "unpckhpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1080 { "unpckhps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1081 { "unpcklpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1082 { "unpcklps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1083 { "verr", Op_SrcMemNTF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1084 { "verw", Op_SrcMemNTF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1085 { "wait", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1086 { "wbinvd", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1087 { "wrmsr", Op_0 },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1088 { "xadd", Op_UpdUpdF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1089 { "xchg", Op_UpdUpd },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1090 { "xlat", Op_xlat },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1091 { "xlatb", Op_0_AX },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1092 { "xor", Op_DstSrcF },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1093 { "xorpd", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1094 { "xorps", Op_DstSrcSSE },
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1095 };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1096
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1097 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1098 Default_Ptr = 0,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1099 Byte_Ptr = 1,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1100 Short_Ptr = 2,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1101 Int_Ptr = 4,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1102 QWord_Ptr = 8,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1103 Float_Ptr = 4,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1104 Double_Ptr = 8,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1105 Extended_Ptr = 10,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1106 Near_Ptr = 98,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1107 Far_Ptr = 99,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1108 N_PtrTypes
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1109 } PtrType;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1110
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1111 static const int N_PtrNames = 8;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1112 static const char * ptrTypeNameTable[N_PtrNames] = {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1113 "word", "dword", "qword",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1114 "float", "double", "extended",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1115 "near", "far"
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1116 };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1117
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1118 static Identifier * ptrTypeIdentTable[N_PtrNames];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1119 static PtrType ptrTypeValueTable[N_PtrNames] = {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1120 Short_Ptr, Int_Ptr, QWord_Ptr,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1121 Float_Ptr, Double_Ptr, Extended_Ptr,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1122 Near_Ptr, Far_Ptr
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1123 };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1124
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1125 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1126 Opr_Invalid,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1127 Opr_Immediate,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1128 Opr_Reg,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1129 Opr_Mem
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1130 } OperandClass;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1131
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1132 /* kill inlining if we reference a local? */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1133
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1134 /* DMD seems to allow only one 'symbol' per operand .. include __LOCAL_SIZE */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1135
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1136 /* DMD offset usage: <parm>[<reg>] seems to always be relative to EBP+8 .. even
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1137 if naked.. */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1138
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1139 // mov eax, 4
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1140 // mov eax, fs:4
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1141 // -- have to assume we know wheter or not to use '$'
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1142
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1143 static Token eof_tok;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1144 static Expression * Handled;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1145 static Identifier * ident_seg;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1146
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1147 struct AsmProcessor
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1148 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1149 typedef struct {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1150 int inBracket;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1151 int hasBracket;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1152 int hasNumber;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1153 int isOffset;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1154
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1155 Reg segmentPrefix;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1156 Reg reg;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1157 sinteger_t constDisplacement; // use to build up.. should be int constant in the end..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1158 Array symbolDisplacement; // array of expressions or..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1159 Reg baseReg;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1160 Reg indexReg;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1161 int scale;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1162
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1163 OperandClass cls;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1164 PtrType dataSize;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1165 PtrType dataSizeHint; // DMD can use the type of a referenced variable
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1166 } Operand;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1167
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1168 static const unsigned Max_Operands = 3;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1169
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1170 AsmStatement * stmt;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1171 Scope * sc;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1172
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1173 Token * token;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1174 OutBuffer * insnTemplate;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1175
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1176 AsmOp op;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1177 AsmOpInfo * opInfo;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1178 Operand operands[Max_Operands];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1179 Identifier * opIdent;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1180 Operand * operand;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1181
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1182 AsmProcessor(Scope * sc, AsmStatement * stmt)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1183 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1184 this->sc = sc;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1185 this->stmt = stmt;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1186 token = stmt->tokens;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1187 insnTemplate = new OutBuffer;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1188
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1189 opInfo = NULL;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1190
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1191 if ( ! regInfo[0].ident ) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1192 char buf[8], *p;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1193
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1194 for (int i = 0; i < N_Regs; i++) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1195 strncpy(buf, regInfo[i].name, sizeof(buf) - 1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1196 for (p = buf; *p; p++)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1197 *p = std::tolower(*p);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1198 regInfo[i].gccName = std::string(buf, p - buf);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1199 if ( (i <= Reg_ST || i > Reg_ST7) && i != Reg_EFLAGS )
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1200 regInfo[i].ident = Lexer::idPool(regInfo[i].name);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1201 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1202
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1203 for (int i = 0; i < N_PtrNames; i++)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1204 ptrTypeIdentTable[i] = Lexer::idPool(ptrTypeNameTable[i]);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1205
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1206 Handled = new Expression(0, TOKvoid, sizeof(Expression));
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1207
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1208 ident_seg = Lexer::idPool("seg");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1209
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1210 eof_tok.value = TOKeof;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1211 eof_tok.next = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1212 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1213 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1214
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1215 void run()
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1216 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1217 parse();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1218 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1220 void nextToken() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1221 if (token->next)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1222 token = token->next;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1223 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1224 token = & eof_tok;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1225 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1226
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1227 Token * peekToken() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1228 if (token->next)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1229 return token->next;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1230 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1231 return & eof_tok;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1232 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1233
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1234 void expectEnd() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1235 if (token->value != TOKeof)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1236 stmt->error("expected end of statement"); // %% extra at end...
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1237 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1238
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1239 void parse() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1240 op = parseOpcode();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1241
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1242 switch (op) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1243 case Op_Align:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1244 doAlign();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1245 expectEnd();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1246 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1247 case Op_Even:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1248 doEven();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1249 expectEnd();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1250 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1251 case Op_Naked:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1252 doNaked();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1253 expectEnd();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1254 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1255 case Op_Invalid:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1256 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1257 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1258 if (op >= Op_db && op <= Op_de)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1259 doData();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1260 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1261 doInstruction();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1262 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1263 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1264
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1265 AsmOp parseOpcode() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1266 static const int N_ents = sizeof(opData)/sizeof(AsmOpEnt);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1267
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1268 switch (token->value) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1269 case TOKalign:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1270 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1271 return Op_Align;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1272 case TOKin:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1273 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1274 opIdent = Id::___in;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1275 return Op_in;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1276 case TOKint32: // "int"
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1277 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1278 opIdent = Id::__int;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1279 return Op_SrcImm;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1280 case TOKout:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1281 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1282 opIdent = Id::___out;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1283 return Op_out;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1284 case TOKidentifier:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1285 // search for mnemonic below
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1286 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1287 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1288 stmt->error("expected opcode");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1289 return Op_Invalid;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1290 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1291
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1292 opIdent = token->ident;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1293 const char * opcode = token->ident->string;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1294
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1295 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1296
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1297 // %% okay to use bsearch?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1298 int i = 0, j = N_ents, k, l;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1299 do {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1300 k = (i + j) / 2;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1301 l = strcmp(opcode, opData[k].inMnemonic);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1302 if (! l)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1303 return opData[k].asmOp;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1304 else if (l < 0)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1305 j = k;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1306 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1307 i = k + 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1308 } while (i != j);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1309
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1310 stmt->error("unknown opcode '%s'", opcode);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1311
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1312 return Op_Invalid;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1313 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1314
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1315 // need clobber information.. use information is good too...
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1316 void doInstruction() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1317 bool ok = true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1318 unsigned operand_i = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1319
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1320 opInfo = & asmOpInfo[op];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1321 memset(operands, 0, sizeof(operands));
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1322
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1323 while (token->value != TOKeof) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1324 if (operand_i < Max_Operands) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1325 operand = & operands[operand_i];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1326 operand->reg = operand->baseReg = operand->indexReg =
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1327 operand->segmentPrefix = Reg_Invalid;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1328 parseOperand();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1329 operand_i++;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1330 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1331 ok = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1332 stmt->error("too many operands for instruction");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1333 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1334 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1335
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1336 if (token->value == TOKcomma)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1337 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1338 else if (token->value != TOKeof) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1339 ok = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1340 stmt->error("expected comma after operand");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1341 return;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1342 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1343 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1344 // if (operand_i < opInfo->minOperands) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1345 // ok = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1346 // stmt->error("too few operands for instruction");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1347 // }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1348
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1349 if ( matchOperands(operand_i) ) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1350 AsmCode * asmcode = new AsmCode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1351
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1352 if (formatInstruction(operand_i, asmcode))
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1353 stmt->asmcode = (code *) asmcode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1354 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1355 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1356
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1357 void setAsmCode() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1358 AsmCode * asmcode = new AsmCode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1359 asmcode->insnTemplateLen = insnTemplate->offset;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1360 asmcode->insnTemplate = (char*) insnTemplate->extractData();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1361 stmt->asmcode = (code*) asmcode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1362 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1363
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1364 // note: doesn't update AsmOp op
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1365 bool matchOperands(unsigned nOperands) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1366 bool wrong_number = true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1367
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1368 for (unsigned i = 0; i < nOperands; i++)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1369 classifyOperand(& operands[i]);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1370
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1371 while (1) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1372 if (nOperands == opInfo->nOperands()) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1373 wrong_number = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1374 /* Cases in which number of operands is not
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1375 enough for a match: Op_FCmp/Op_FCmp1,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1376 Op_FCmpP/Op_FCmpP1 */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1377 for (unsigned i = 0; i < nOperands; i++) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1378 Operand * operand = & operands[i];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1379
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1380 switch (opInfo->operands[i] & Opr_ClassMask) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1381 case OprC_Mem: // no FPMem currently
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1382 if (operand->cls != Opr_Mem)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1383 goto no_match;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1384 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1385 case OprC_RFP:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1386 if (! (operand->reg >= Reg_ST && operand->reg <= Reg_ST7))
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1387 goto no_match;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1388 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1389 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1390 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1391 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1392 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1393
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1394 return true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1395 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1396 no_match:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1397 if (opInfo->linkType == Next_Form)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1398 opInfo = & asmOpInfo[ op = (AsmOp) opInfo->link ];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1399 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1400 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1401 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1402 if (wrong_number)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1403 stmt->error("wrong number of operands");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1404 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1405 stmt->error("wrong operand types");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1406 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1407 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1408
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1409 void addOperand(const char * fmt, AsmArgType type, Expression * e, AsmCode * asmcode, AsmArgMode mode = Mode_Input) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1410 insnTemplate->writestring((char*) fmt);
234
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 232
diff changeset
1411 insnTemplate->printf("<<%s%d>>", (mode==Mode_Input)?"in":"out", asmcode->args.dim);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1412 asmcode->args.push( new AsmArg(type, e, mode) );
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1413 }
231
61aa721a6b7f [svn r247] fixed accessing global symbols from inline asm.
lindquist
parents: 229
diff changeset
1414 void addOperand2(const char * fmtpre, const char * fmtpost, AsmArgType type, Expression * e, AsmCode * asmcode, AsmArgMode mode = Mode_Input) {
61aa721a6b7f [svn r247] fixed accessing global symbols from inline asm.
lindquist
parents: 229
diff changeset
1415 insnTemplate->writestring((char*) fmtpre);
234
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 232
diff changeset
1416 insnTemplate->printf("<<%s%d>>", (mode==Mode_Input)?"in":"out", asmcode->args.dim);
231
61aa721a6b7f [svn r247] fixed accessing global symbols from inline asm.
lindquist
parents: 229
diff changeset
1417 insnTemplate->writestring((char*) fmtpost);
61aa721a6b7f [svn r247] fixed accessing global symbols from inline asm.
lindquist
parents: 229
diff changeset
1418 asmcode->args.push( new AsmArg(type, e, mode) );
61aa721a6b7f [svn r247] fixed accessing global symbols from inline asm.
lindquist
parents: 229
diff changeset
1419 }
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1420
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1421 void addLabel(unsigned n) {
229
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
1422 // No longer taking the address of the actual label -- doesn't seem like it would help.
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
1423 char buf[64];
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
1424
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
1425 d_format_priv_asm_label(buf, n);
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
1426 insnTemplate->writestring(buf);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1427 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1428
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1429 void addLabel(char* id) {
234
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 232
diff changeset
1430 insnTemplate->writestring(".LDASM_");
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1431 insnTemplate->writestring(id);
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1432 }
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1433
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1434 /* Determines whether the operand is a register, memory reference
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1435 or immediate. Immediate addresses are currently classified as
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1436 memory. This function is called before the exact instructions
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1437 is known and thus, should not use opInfo. */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1438 void classifyOperand(Operand * operand) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1439 operand->cls = classifyOperand1(operand);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1440 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1441
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1442 OperandClass classifyOperand1(Operand * operand) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1443 bool is_localsize = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1444 bool really_have_symbol = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1445
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1446 if (operand->symbolDisplacement.dim) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1447 is_localsize = isLocalSize( (Expression *) operand->symbolDisplacement.data[0] );
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1448 really_have_symbol = ! is_localsize;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1449 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1450
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1451 if (operand->isOffset && ! operand->hasBracket)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1452 return Opr_Immediate;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1453
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1454 if (operand->hasBracket || really_have_symbol) { // %% redo for 'offset' function
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1455 if (operand->reg != Reg_Invalid) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1456 invalidExpression();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1457 return Opr_Invalid;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1458 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1459
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1460 return Opr_Mem;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1461 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1462
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1463 if (operand->reg != Reg_Invalid && operand->constDisplacement != 0) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1464 invalidExpression();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1465 return Opr_Invalid;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1466 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1467
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1468 if (operand->segmentPrefix != Reg_Invalid) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1469 if (operand->reg != Reg_Invalid) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1470 invalidExpression();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1471 return Opr_Invalid;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1472 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1473
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1474 return Opr_Mem;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1475 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1476
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1477 if (operand->reg != Reg_Invalid && ! operand->hasNumber)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1478 return Opr_Reg;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1479
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1480 // should check immediate given (operand->hasNumber);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1481 //
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1482 if (operand->hasNumber || is_localsize) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1483 // size determination not correct if there are symbols Opr_Immediate
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1484 if (operand->dataSize == Default_Ptr) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1485 if (operand->constDisplacement < 0x100)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1486 operand->dataSize = Byte_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1487 else if (operand->constDisplacement < 0x10000)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1488 operand->dataSize = Short_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1489 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1490 operand->dataSize = Int_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1491 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1492 return Opr_Immediate;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1493 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1494
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1495 // probably a bug,?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1496 stmt->error("invalid operand");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1497 return Opr_Invalid;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1498 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1499
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1500 void writeReg(Reg reg) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1501 insnTemplate->writestring((char*) "%");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1502 insnTemplate->write(regInfo[reg].gccName.c_str(), regInfo[reg].gccName.length());
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1503 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1504
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1505 bool opTakesLabel() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1506 switch(op) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1507 case Op_Branch:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1508 case Op_CBranch:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1509 case Op_Loop:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1510 return true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1511 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1512 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1513 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1514 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1515
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1516 bool getTypeChar(TypeNeeded needed, PtrType ptrtype, char & type_char)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1517 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1518 switch (needed) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1519 case Byte_NoType:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1520 return ptrtype == Byte_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1521 case Word_Types:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1522 if (ptrtype == Byte_Ptr)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1523 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1524 // drop through
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1525 case Int_Types:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1526 switch (ptrtype) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1527 case Byte_Ptr: type_char = 'b'; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1528 case Short_Ptr: type_char = 'w'; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1529 case Int_Ptr: type_char = 'l'; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1530 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1531 // %% these may be too strict
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1532 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1533 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1534 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1535 case FPInt_Types:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1536 switch (ptrtype) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1537 case Short_Ptr: type_char = 0; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1538 case Int_Ptr: type_char = 'l'; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1539 case QWord_Ptr: type_char = 'q'; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1540 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1541 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1542 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1543 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1544 case FP_Types:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1545 switch (ptrtype) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1546 case Float_Ptr: type_char = 's'; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1547 case Double_Ptr: type_char = 'l'; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1548 case Extended_Ptr: type_char = 't'; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1549 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1550 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1551 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1552 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1553 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1554 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1555 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1556 return true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1557 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1558
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1559 // also set impl clobbers
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1560 bool formatInstruction(int nOperands, AsmCode * asmcode) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1561 const char *fmt;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1562 const char *mnemonic;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1563 char type_char = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1564 bool use_star;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1565 AsmArgMode mode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1566
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1567 insnTemplate = new OutBuffer;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1568 // %% todo: special case for something..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1569 if (opInfo->linkType == Out_Mnemonic)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1570 mnemonic = alternateMnemonics[opInfo->link];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1571 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1572 mnemonic = opIdent->string;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1573
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1574 if (opInfo->needsType) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1575 PtrType exact_type = Default_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1576 PtrType min_type = Default_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1577 PtrType hint_type = Default_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1578
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1579 /* Default types: This attempts to match the observed behavior of DMD */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1580 switch (opInfo->needsType) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1581 case Int_Types: min_type = Byte_Ptr; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1582 case Word_Types: min_type = Short_Ptr; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1583 case FPInt_Types:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1584 if (op == Op_Fis_ST) // integer math instructions
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1585 min_type = Int_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1586 else // compare, load, store
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1587 min_type = Short_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1588 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1589 case FP_Types: min_type = Float_Ptr; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1590 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1591 if (op == Op_push && operands[0].cls == Opr_Immediate)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1592 min_type = Int_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1593
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1594 for (int i = 0; i < nOperands; i++) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1595 if (hint_type == Default_Ptr &&
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1596 ! (opInfo->operands[i] & Opr_NoType))
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1597 hint_type = operands[i].dataSizeHint;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1598
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1599 if ((opInfo->operands[i] & Opr_NoType) ||
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1600 operands[i].dataSize == Default_Ptr)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1601 continue;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1602 if (operands[i].cls == Opr_Immediate) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1603 min_type = operands[i].dataSize > min_type ?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1604 operands[i].dataSize : min_type;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1605 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1606 exact_type = operands[i].dataSize; // could check for conflicting types
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1607 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1608 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1609 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1610
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1611 bool type_ok;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1612 if (exact_type == Default_Ptr) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1613 type_ok = getTypeChar((TypeNeeded) opInfo->needsType, hint_type, type_char);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1614 if (! type_ok)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1615 type_ok = getTypeChar((TypeNeeded) opInfo->needsType, min_type, type_char);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1616 } else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1617 type_ok = getTypeChar((TypeNeeded) opInfo->needsType, exact_type, type_char);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1618
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1619 if (! type_ok) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1620 stmt->error("invalid operand size");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1621 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1622 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1623 } else if (op == Op_Branch) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1624 if (operands[0].dataSize == Far_Ptr) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1625 insnTemplate->writebyte('l');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1626 } else if (op == Op_fxch) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1627 // gas won't accept the two-operand form
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1628 if (operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1629 nOperands = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1630 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1631 stmt->error("invalid operands");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1632 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1633 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1634 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1635
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1636 switch (op) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1637 case Op_SizedStack:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1638 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1639 int mlen = strlen(mnemonic);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1640 if (mnemonic[mlen-1] == 'd')
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1641 insnTemplate->write(mnemonic, mlen-1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1642 else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1643 insnTemplate->writestring((char*) mnemonic);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1644 insnTemplate->writebyte('w');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1645 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1646 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1647 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1648 case Op_cmpsd:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1649 case Op_insX:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1650 case Op_lodsX:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1651 case Op_movsd:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1652 case Op_outsX:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1653 case Op_scasX:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1654 case Op_stosX:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1655 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1656 int mlen = strlen(mnemonic);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1657 if (mnemonic[mlen-1] == 'd') {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1658 insnTemplate->write(mnemonic, mlen-1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1659 insnTemplate->writebyte('l');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1660 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1661 insnTemplate->writestring((char*) mnemonic);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1662 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1663 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1664 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1665 case Op_movsx:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1666 case Op_movzx:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1667 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1668 char tc_1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1669 int mlen = strlen(mnemonic);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1670 PtrType op1_size = operands[1].dataSize;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1671 if (op1_size == Default_Ptr)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1672 op1_size = operands[1].dataSizeHint;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1673 // Need type char for source arg
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1674 switch (op1_size) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1675 case Byte_Ptr:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1676 case Default_Ptr:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1677 tc_1 = 'b';
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1678 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1679 case Short_Ptr:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1680 tc_1 = 'w';
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1681 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1682 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1683 stmt->error("invalid operand size/type");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1684 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1685 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1686 assert(type_char != 0);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1687 insnTemplate->write(mnemonic, mlen-1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1688 insnTemplate->writebyte(tc_1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1689 insnTemplate->writebyte(type_char);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1690 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1691 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1692 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1693 insnTemplate->writestring((char*) mnemonic);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1694 if (type_char)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1695 insnTemplate->writebyte(type_char);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1696 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1697 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1698
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1699 switch (opInfo->implicitClobbers & Clb_DXAX_Mask) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1700 case Clb_SizeAX:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1701 case Clb_EAX:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1702 stmt->regs |= (1<<Reg_EAX);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1703 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1704 case Clb_SizeDXAX:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1705 stmt->regs |= (1<<Reg_EAX);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1706 if (type_char != 'b')
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1707 stmt->regs |= (1<<Reg_EDX);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1708 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1709 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1710 // nothing
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1711 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1712 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1713
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1714 if (opInfo->implicitClobbers & Clb_DI)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1715 stmt->regs |= (1 << Reg_EDI);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1716 if (opInfo->implicitClobbers & Clb_SI)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1717 stmt->regs |= (1 << Reg_ESI);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1718 if (opInfo->implicitClobbers & Clb_CX)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1719 stmt->regs |= (1 << Reg_ECX);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1720 if (opInfo->implicitClobbers & Clb_SP)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1721 stmt->regs |= (1 << Reg_ESP);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1722 if (opInfo->implicitClobbers & Clb_ST)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1723 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1724 /* Can't figure out how to tell GCC that an
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1725 asm statement leaves an arg pushed on the stack.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1726 Maybe if the statment had and input or output
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1727 operand it would work... In any case, clobbering
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1728 all FP prevents incorrect code generation. */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1729 stmt->regs |= (1 << Reg_ST);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1730 stmt->regs |= (1 << Reg_ST1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1731 stmt->regs |= (1 << Reg_ST2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1732 stmt->regs |= (1 << Reg_ST3);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1733 stmt->regs |= (1 << Reg_ST4);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1734 stmt->regs |= (1 << Reg_ST5);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1735 stmt->regs |= (1 << Reg_ST6);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1736 stmt->regs |= (1 << Reg_ST7);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1737 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1738 if (opInfo->implicitClobbers & Clb_Flags)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1739 asmcode->moreRegs |= (1 << (Reg_EFLAGS - 32));
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1740 if (op == Op_cpuid)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1741 stmt->regs |= (1 << Reg_EAX)|
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1742 (1 << Reg_ECX)|(1 << Reg_EDX);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1743
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
1744 insnTemplate->writebyte(' ');
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1745 for (int i__ = 0; i__ < nOperands; i__++) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1746 int i;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1747 if (i__ != 0)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1748 insnTemplate->writestring((char*) ", ");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1749
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1750 fmt = "$";
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1751
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1752 switch (op) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1753 case Op_mul:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1754 // gas won't accept the two-operand form; skip to the source operand
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1755 i__ = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1756 // drop through
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1757 case Op_bound:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1758 case Op_enter:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1759 i = i__;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1760 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1761 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1762 i = nOperands - 1 - i__; // operand = & operands[ nOperands - 1 - i ];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1763 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1764 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1765 operand = & operands[ i ];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1766
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1767 switch (operand->cls) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1768 case Opr_Immediate:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1769 // for implementing offset:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1770 // $var + $7 // fails
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1771 // $var + 7 // ok
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1772 // $7 + $var // ok
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1773
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1774 // DMD doesn't seem to allow this
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1775 /*
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1776 if (opInfo->takesLabel()) tho... (near ptr <Number> would be abs?)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1777 fmt = "$a"; // GAS won't accept "jmp $42"; must be "jmp 42" (rel) or "jmp *42" (abs)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1778 */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1779 if (opTakesLabel()/*opInfo->takesLabel()*/) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1780 // "relative addressing not allowed in branch instructions" ..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1781 stmt->error("integer constant not allowed in branch instructions");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1782 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1783 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1784
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1785 if (operand->symbolDisplacement.dim &&
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1786 isLocalSize( (Expression *) operand->symbolDisplacement.data[0] )) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1787 // handle __LOCAL_SIZE, which in this constant, is an immediate
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1788 // should do this in slotexp..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1789 addOperand("$", Arg_LocalSize,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1790 (Expression *) operand->symbolDisplacement.data[0], asmcode);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1791 if (operand->constDisplacement)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1792 insnTemplate->writebyte('+');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1793 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1794 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1795 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1796
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1797 if (operand->symbolDisplacement.dim) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1798 fmt = "$a";
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1799 addOperand("$", Arg_Pointer,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1800 (Expression *) operand->symbolDisplacement.data[0],
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1801 asmcode);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1802
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1803 if (operand->constDisplacement)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1804 insnTemplate->writebyte('+');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1805 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1806 // skip the addOperand(fmt, Arg_Integer...) below
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1807 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1808 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1809 addOperand(fmt, Arg_Integer, newIntExp(operand->constDisplacement), asmcode);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1810 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1811 case Opr_Reg:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1812 if (opInfo->operands[i] & Opr_Dest) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1813 Reg clbr_reg = (Reg) regInfo[operand->reg].baseReg;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1814 if (clbr_reg != Reg_Invalid) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1815 if (clbr_reg < 32)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1816 stmt->regs |= (1 << clbr_reg);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1817 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1818 asmcode->moreRegs |= (1 << (clbr_reg - 32));
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1819 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1820 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1821 if (opTakesLabel()/*opInfo->takesLabel()*/)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1822 insnTemplate->writebyte('*');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1823 writeReg(operand->reg);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1824 /*
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1825 insnTemplate->writestring("%");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1826 insnTemplate->writestring(regInfo[operand->reg].name);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1827 */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1828 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1829 case Opr_Mem:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1830 // better: use output operands for simple variable references
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1831 if ( (opInfo->operands[i] & Opr_Update) == Opr_Update) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1832 mode = Mode_Update;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1833 } else if (opInfo->operands[i] & Opr_Dest) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1834 mode = Mode_Output;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1835 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1836 mode = Mode_Input;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1837 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1838
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1839 use_star = opTakesLabel();//opInfo->takesLabel();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1840 if (operand->segmentPrefix != Reg_Invalid) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1841 writeReg(operand->segmentPrefix);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1842 insnTemplate->writebyte(':');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1843 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1844 if (operand->symbolDisplacement.dim) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1845 Expression * e = (Expression *) operand->symbolDisplacement.data[0];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1846 Declaration * decl = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1847
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1848 if (e->op == TOKvar)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1849 decl = ((VarExp *) e)->var;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1850
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1851 if (operand->baseReg != Reg_Invalid &&
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1852 decl && ! decl->isDataseg()) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1853
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1854 // Use the offset from frame pointer
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1855
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1856 /* GCC doesn't give the front end access to stack offsets
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1857 when optimization is turned on (3.x) or at all (4.x).
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1858
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1859 Try to convert var[EBP] (or var[ESP] for naked funcs) to
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1860 a memory expression that does not require us to know
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1861 the stack offset.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1862 */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1863
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1864 if (operand->indexReg == Reg_Invalid &&
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1865 decl->isVarDeclaration() &&
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1866 ((operand->baseReg == Reg_EBP && ! sc->func->naked ) ||
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1867 (operand->baseReg == Reg_ESP && sc->func->naked)) ) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1868
221
68687d8c3e9a [svn r237] some inline asm output now seems to work, see tangotests/asm2.d
lindquist
parents: 220
diff changeset
1869 if (mode == Mode_Output)
68687d8c3e9a [svn r237] some inline asm output now seems to work, see tangotests/asm2.d
lindquist
parents: 220
diff changeset
1870 {
68687d8c3e9a [svn r237] some inline asm output now seems to work, see tangotests/asm2.d
lindquist
parents: 220
diff changeset
1871 e = new AddrExp(0, e);
68687d8c3e9a [svn r237] some inline asm output now seems to work, see tangotests/asm2.d
lindquist
parents: 220
diff changeset
1872 e->type = decl->type->pointerTo();
68687d8c3e9a [svn r237] some inline asm output now seems to work, see tangotests/asm2.d
lindquist
parents: 220
diff changeset
1873 }
68687d8c3e9a [svn r237] some inline asm output now seems to work, see tangotests/asm2.d
lindquist
parents: 220
diff changeset
1874
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
1875 #if !IN_LLVM
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1876 /* DMD uses the same frame offsets for naked functions. */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1877 if (sc->func->naked)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1878 operand->constDisplacement += 4;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1879
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1880 if (operand->constDisplacement) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1881 e = new AddExp(0, e,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1882 new IntegerExp(0, operand->constDisplacement,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1883 Type::tint32));
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1884 e->type = decl->type->pointerTo();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1885 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1886 e = new PtrExp(0, e);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1887 e->type = decl->type;
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
1888 #endif
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1889 operand->constDisplacement = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1890 operand->baseReg = Reg_Invalid;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1891
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1892 addOperand(fmt, Arg_Memory, e, asmcode, mode);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1893
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1894 } else {
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1895 addOperand2("${",":a}", Arg_FrameRelative, e, asmcode);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1896 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1897 if (opInfo->operands[i] & Opr_Dest)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1898 asmcode->clobbersMemory = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1899 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1900 // Plain memory reference to variable
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1901
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1902 /* If in a reg, DMD moves to memory.. even with -O, so we'll do the same
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1903 by always using the "m" contraint.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1904
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1905 In order to get the correct output for function and label symbols,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1906 the %an format must be used with the "p" constraint.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1907 */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1908 if (isDollar(e)) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1909 unsigned lbl_num = ++d_priv_asm_label_serial;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1910 addLabel(lbl_num);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1911 asmcode->dollarLabel = lbl_num; // could make the dollar label part of the same asm..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1912 } else if (e->op == TOKdsymbol) {
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1913 LabelDsymbol * lbl = (LabelDsymbol *) ((DsymbolExp *) e)->s;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1914 if (! lbl->asmLabelNum)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1915 lbl->asmLabelNum = ++d_priv_asm_label_serial;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1916
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1917 use_star = false;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1918 addLabel(lbl->ident->toChars());
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1919 } else if ((decl && decl->isCodeseg())) { // if function or label
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1920 use_star = false;
231
61aa721a6b7f [svn r247] fixed accessing global symbols from inline asm.
lindquist
parents: 229
diff changeset
1921 addOperand2("${", ":c}", Arg_Pointer, e, asmcode);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1922 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1923 if (use_star) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1924 insnTemplate->writebyte('*');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1925 use_star = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1926 }
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1927 Type* tt = e->type->pointerTo();
222
251548c1035d [svn r238] use *m for memory input constraints and pass in their address
ChristianK
parents: 221
diff changeset
1928 e = new AddrExp(0, e);
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1929 e->type = tt;
222
251548c1035d [svn r238] use *m for memory input constraints and pass in their address
ChristianK
parents: 221
diff changeset
1930
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1931 addOperand(fmt, Arg_Memory, e, asmcode, mode);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1932 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1933 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1934 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1935 if (use_star)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1936 insnTemplate->writebyte('*');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1937 if (operand->constDisplacement) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1938 if (operand->symbolDisplacement.dim)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1939 insnTemplate->writebyte('+');
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
1940 addOperand2("${",":a}", Arg_Integer, newIntExp(operand->constDisplacement), asmcode);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1941 if (opInfo->operands[i] & Opr_Dest)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1942 asmcode->clobbersMemory = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1943 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1944 if (operand->baseReg != Reg_Invalid || operand->indexReg != Reg_Invalid) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1945 insnTemplate->writebyte('(');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1946 if (operand->baseReg != Reg_Invalid)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1947 writeReg(operand->baseReg);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1948 if (operand->indexReg != Reg_Invalid) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1949 insnTemplate->writebyte(',');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1950 writeReg(operand->indexReg);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1951 if (operand->scale) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1952 insnTemplate->printf(",%d", operand->scale);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1953 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1954 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1955 insnTemplate->writebyte(')');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1956 if (opInfo->operands[i] & Opr_Dest)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1957 asmcode->clobbersMemory = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1958 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1959 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1960 case Opr_Invalid:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1961 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1962 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1963 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1964
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1965 asmcode->insnTemplateLen = insnTemplate->offset;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1966 asmcode->insnTemplate = (char*) insnTemplate->extractData();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1967 return true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1968 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1969
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1970 bool isIntExp(Expression * exp) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1971 if (exp->op == TOKint64)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1972 return 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1973 if (exp->op == TOKvar) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1974 Declaration * v = ((VarExp *) exp)->var;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1975 if (v->isConst() && v->type->isintegral())
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1976 return 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1977 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1978 return 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1979 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1980 bool isRegExp(Expression * exp) { return exp->op == TOKmod; } // ewww.%%
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1981 bool isLocalSize(Expression * exp) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1982 // cleanup: make a static var
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1983 return exp->op == TOKidentifier && ((IdentifierExp *) exp)->ident == Id::__LOCAL_SIZE;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1984 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1985 bool isDollar(Expression * exp) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1986 return exp->op == TOKidentifier && ((IdentifierExp *) exp)->ident == Id::__dollar;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1987 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1988
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1989 Expression * newRegExp(int regno) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1990 IntegerExp * e = new IntegerExp(regno);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1991 e->op = TOKmod;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1992 return e;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1993 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1994
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1995 Expression * newIntExp(int v /* %% type */) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1996 // Only handles 32-bit numbers as this is IA-32.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1997 return new IntegerExp(stmt->loc, v, Type::tint32);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1998 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
1999
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2000 void slotExp(Expression * exp) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2001 /*
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2002 if offset, make a note
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2003
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2004 if integer, add to immediate
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2005 if reg:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2006 if not in bracket, set reg (else error)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2007 if in bracket:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2008 if not base, set base
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2009 if not index, set index
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2010 else, error
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2011 if symbol:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2012 set symbol field
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2013 */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2014
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2015 bool is_offset = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2016 if (exp->op == TOKaddress) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2017 exp = ((AddrExp *) exp)->e1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2018 is_offset = true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2019 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2020
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2021 if (isIntExp(exp)) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2022 if (is_offset)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2023 invalidExpression();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2024 operand->constDisplacement += exp->toInteger();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2025 if (! operand->inBracket)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2026 operand->hasNumber = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2027 } else if (isRegExp(exp)) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2028 if (is_offset)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2029 invalidExpression();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2030 if (! operand->inBracket) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2031 if (operand->reg == Reg_Invalid)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2032 operand->reg = (Reg) exp->toInteger();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2033 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2034 stmt->error("too many registers in operand (use brackets)");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2035 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2036 if (operand->baseReg == Reg_Invalid)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2037 operand->baseReg = (Reg) exp->toInteger();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2038 else if (operand->indexReg == Reg_Invalid) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2039 operand->indexReg = (Reg) exp->toInteger();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2040 operand->scale = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2041 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2042 stmt->error("too many registers memory operand");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2043 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2044 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2045 } else if (exp->op == TOKvar) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2046 VarDeclaration * v = ((VarExp *) exp)->var->isVarDeclaration();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2047
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2048 if (v && v->storage_class & STCfield) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2049 operand->constDisplacement += v->offset;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2050 if (! operand->inBracket)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2051 operand->hasNumber = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2052 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2053 if (v && v->type->isscalar())
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2054 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2055 // DMD doesn't check Tcomplex*, and counts Tcomplex32 as Tfloat64
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2056 TY ty = v->type->toBasetype()->ty;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2057 operand->dataSizeHint = ty == Tfloat80 || ty == Timaginary80 ?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2058 Extended_Ptr : (PtrType) v->type->size(0);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2059 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2060
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2061 if (! operand->symbolDisplacement.dim) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2062 if (is_offset && ! operand->inBracket)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2063 operand->isOffset = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2064 operand->symbolDisplacement.push( exp );
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2065 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2066 stmt->error("too many symbols in operand");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2067 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2068 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2069 } else if (exp->op == TOKidentifier || exp->op == TOKdsymbol) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2070 // %% localsize could be treated as a simple constant..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2071 // change to addSymbolDisp(e)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2072 if (! operand->symbolDisplacement.dim) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2073 operand->symbolDisplacement.push( exp );
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2074 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2075 stmt->error("too many symbols in operand");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2076 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2077 } else if (exp == Handled) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2078 // nothing
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2079 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2080 stmt->error("invalid operand");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2081 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2082 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2083
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2084 void invalidExpression() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2085 // %% report operand number
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2086 stmt->error("invalid expression");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2087 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2088
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2089 Expression * intOp(TOK op, Expression * e1, Expression * e2) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2090 Expression * e;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2091 if (isIntExp(e1) && (! e2 || isIntExp(e2))) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2092 switch (op) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2093 case TOKadd:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2094 if (e2)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2095 e = new AddExp(stmt->loc, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2096 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2097 e = e1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2098 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2099 case TOKmin:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2100 if (e2)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2101 e = new MinExp(stmt->loc, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2102 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2103 e = new NegExp(stmt->loc, e1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2104 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2105 case TOKmul:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2106 e = new MulExp(stmt->loc, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2107 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2108 case TOKdiv:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2109 e = new DivExp(stmt->loc, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2110 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2111 case TOKmod:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2112 e = new ModExp(stmt->loc, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2113 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2114 case TOKshl:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2115 e = new ShlExp(stmt->loc, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2116 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2117 case TOKshr:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2118 e = new ShrExp(stmt->loc, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2119 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2120 case TOKushr:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2121 e = new UshrExp(stmt->loc, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2122 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2123 case TOKnot:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2124 e = new NotExp(stmt->loc, e1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2125 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2126 case TOKtilde:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2127 e = new ComExp(stmt->loc, e1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2128 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2129 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2130 assert(0);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2131 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2132 e = e->semantic(sc);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2133 return e->optimize(WANTvalue | WANTinterpret);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2134 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2135 stmt->error("expected integer operand(s) for '%s'", Token::tochars[op]);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2136 return newIntExp(0);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2137 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2138 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2139
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2140 void parseOperand() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2141 Expression * exp = parseAsmExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2142 slotExp(exp);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2143 if (isRegExp(exp))
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2144 operand->dataSize = (PtrType) regInfo[exp->toInteger()].size;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2145 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2146
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2147 Expression * parseAsmExp() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2148 return parseShiftExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2149 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2150
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2151 Expression * parseShiftExp() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2152 Expression * e1 = parseAddExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2153 Expression * e2;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2154
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2155 while (1) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2156 TOK tv = token->value;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2157 switch (tv) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2158 case TOKshl:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2159 case TOKshr:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2160 case TOKushr:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2161 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2162 e2 = parseAddExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2163 e1 = intOp(tv, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2164 continue;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2165 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2166 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2167 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2168 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2169 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2170 return e1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2171 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2172
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2173 Expression * parseAddExp() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2174 Expression * e1 = parseMultExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2175 Expression * e2;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2176
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2177 while (1) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2178 TOK tv = token->value;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2179 switch (tv) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2180 case TOKadd:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2181 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2182 e2 = parseMultExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2183 if (isIntExp(e1) && isIntExp(e2))
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2184 e1 = intOp(tv, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2185 else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2186 slotExp(e1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2187 slotExp(e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2188 e1 = Handled;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2189 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2190 continue;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2191 case TOKmin:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2192 // Note: no support for symbol address difference
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2193 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2194 e2 = parseMultExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2195 if (isIntExp(e1) && isIntExp(e2))
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2196 e1 = intOp(tv, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2197 else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2198 slotExp(e1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2199 e2 = intOp(TOKmin, e2, NULL); // verifies e2 is an int
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2200 slotExp(e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2201 e1 = Handled;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2202 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2203 continue;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2204 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2205 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2206 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2207 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2208 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2209 return e1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2210 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2211
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2212 bool tryScale(Expression * e1, Expression * e2) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2213 Expression * et;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2214 if (isIntExp(e1) && isRegExp(e2)) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2215 et = e1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2216 e1 = e2;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2217 e2 = et;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2218 goto do_scale;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2219 } else if (isRegExp(e1) && isIntExp(e2)) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2220 do_scale:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2221 if (! operand->inBracket) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2222 invalidExpression(); // maybe should allow, e.g. DS:EBX+EAX*4
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2223 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2224
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2225 if (operand->scale || operand->indexReg != Reg_Invalid) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2226 invalidExpression();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2227 return true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2228 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2229
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2230 operand->indexReg = (Reg) e1->toInteger();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2231 operand->scale = e2->toInteger();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2232 switch (operand->scale) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2233 case 1:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2234 case 2:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2235 case 4:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2236 case 8:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2237 // ok; do nothing
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2238 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2239 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2240 stmt->error("invalid index register scale '%d'", operand->scale);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2241 return true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2242 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2243
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2244 return true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2245 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2246 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2247 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2248
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2249 Expression * parseMultExp() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2250 Expression * e1 = parseBrExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2251 Expression * e2;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2252
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2253 while (1) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2254 TOK tv = token->value;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2255 switch (tv) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2256 case TOKmul:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2257 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2258 e2 = parseMultExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2259 if (isIntExp(e1) && isIntExp(e2))
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2260 e1 = intOp(tv, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2261 else if (tryScale(e1,e2))
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2262 e1 = Handled;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2263 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2264 invalidExpression();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2265 continue;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2266 case TOKdiv:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2267 case TOKmod:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2268 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2269 e2 = parseMultExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2270 e1 = intOp(tv, e1, e2);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2271 continue;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2272 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2273 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2274 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2275 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2276 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2277 return e1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2278 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2279
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2280 Expression * parseBrExp() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2281 // %% check (why is bracket lower precends..)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2282 // 3+4[eax] -> 3 + (4 [EAX]) ..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2283
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2284 // only one bracked allowed, so this doesn't quite handle
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2285 // the spec'd syntax
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2286 Expression * e;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2287
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2288 if (token->value == TOKlbracket)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2289 e = Handled;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2290 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2291 e = parseUnaExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2292
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2293 // DMD allows multiple bracket expressions.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2294 while (token->value == TOKlbracket) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2295 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2296
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2297 operand->inBracket = operand->hasBracket = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2298 slotExp(parseAsmExp());
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2299 operand->inBracket = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2300
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2301 if (token->value == TOKrbracket)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2302 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2303 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2304 stmt->error("missing ']'");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2305 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2306
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2307 return e;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2308 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2309
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2310 PtrType isPtrType(Token * tok) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2311 switch (tok->value) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2312 case TOKint8: return Byte_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2313 case TOKint16: return Short_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2314 case TOKint32: return Int_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2315 // 'long ptr' isn't accepted?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2316 case TOKfloat32: return Float_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2317 case TOKfloat64: return Double_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2318 case TOKfloat80: return Extended_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2319 case TOKidentifier:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2320 for (int i = 0; i < N_PtrNames; i++)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2321 if (tok->ident == ptrTypeIdentTable[i])
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2322 return ptrTypeValueTable[i];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2323 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2324 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2325 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2326 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2327 return Default_Ptr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2328 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2329
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2330 Expression * parseUnaExp() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2331 Expression * e = NULL;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2332 PtrType ptr_type;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2333
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2334 // First, check for type prefix.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2335 if (token->value != TOKeof &&
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2336 peekToken()->value == TOKidentifier &&
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2337 peekToken()->ident == Id::ptr) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2338
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2339 ptr_type = isPtrType(token);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2340 if (ptr_type != Default_Ptr) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2341 if (operand->dataSize == Default_Ptr)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2342 operand->dataSize = ptr_type;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2343 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2344 stmt->error("multiple specifications of operand size");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2345 } else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2346 stmt->error("unknown operand size '%s'", token->toChars());
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2347 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2348 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2349 return parseAsmExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2350 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2351
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2352 TOK tv = token->value;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2353 switch (tv) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2354 case TOKidentifier:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2355 if (token->ident == ident_seg) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2356 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2357 stmt->error("'seg' not supported");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2358 e = parseAsmExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2359 } else if (token->ident == Id::offset ||
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2360 token->ident == Id::offsetof) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2361 if (token->ident == Id::offset && ! global.params.useDeprecated)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2362 stmt->error("offset deprecated, use offsetof");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2363 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2364 e = parseAsmExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2365 e = new AddrExp(stmt->loc, e);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2366 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2367 // primary exp
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2368 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2369 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2370 return e;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2371 case TOKadd:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2372 case TOKmin:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2373 case TOKnot:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2374 case TOKtilde:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2375 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2376 e = parseUnaExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2377 return intOp(tv, e, NULL);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2378 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2379 // primary exp
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2380 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2381 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2382 return parsePrimaryExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2383 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2384
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2385 Expression * parsePrimaryExp() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2386 Expression * e;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2387 Identifier * ident = NULL;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2388
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2389 switch (token->value) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2390 case TOKint32v:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2391 case TOKuns32v:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2392 case TOKint64v:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2393 case TOKuns64v:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2394 // semantic here?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2395 // %% for tok64 really should use 64bit type
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2396 e = new IntegerExp(stmt->loc, token->uns64value, Type::tint32);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2397 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2398 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2399 case TOKfloat32v:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2400 case TOKfloat64v:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2401 case TOKfloat80v:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2402 // %% need different types?
229
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
2403 if (global.params.useFP80)
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
2404 e = new RealExp(stmt->loc, token->float80value, Type::tfloat80);
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
2405 else
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
2406 e = new RealExp(stmt->loc, token->float80value, Type::tfloat64);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2407 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2408 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2409 case TOKidentifier:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2410 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2411 ident = token->ident;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2412 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2413
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2414 if (ident == Id::__LOCAL_SIZE) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2415 return new IdentifierExp(stmt->loc, ident);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2416 } else if (ident == Id::__dollar) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2417 do_dollar:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2418 return new IdentifierExp(stmt->loc, ident);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2419 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2420 e = new IdentifierExp(stmt->loc, ident);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2421 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2422
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2423 // If this is more than one component ref, it gets complicated: *(&Field + n)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2424 // maybe just do one step at a time..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2425 // simple case is Type.f -> VarDecl(field)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2426 // actually, DMD only supports on level...
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2427 // X.y+Y.z[EBX] is supported, tho..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2428 // %% doesn't handle properties (check%%)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2429 while (token->value == TOKdot) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2430 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2431 if (token->value == TOKidentifier) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2432 e = new DotIdExp(stmt->loc, e, token->ident);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2433 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2434 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2435 stmt->error("expected identifier");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2436 return Handled;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2437 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2438 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2439
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2440 // check for reg first then dotexp is an error?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2441 if (e->op == TOKidentifier) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2442 for (int i = 0; i < N_Regs; i++) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2443 if (ident == regInfo[i].ident) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2444 if ( (Reg) i == Reg_ST && token->value == TOKlparen) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2445 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2446 switch (token->value) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2447 case TOKint32v: case TOKuns32v:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2448 case TOKint64v: case TOKuns64v:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2449 if (token->uns64value < 8)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2450 e = newRegExp( (Reg) (Reg_ST + token->uns64value) );
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2451 else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2452 stmt->error("invalid floating point register index");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2453 e = Handled;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2454 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2455 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2456 if (token->value == TOKrparen)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2457 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2458 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2459 stmt->error("expected ')'");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2460 return e;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2461 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2462 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2463 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2464 invalidExpression();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2465 return Handled;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2466 } else if (token->value == TOKcolon) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2467 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2468 if (operand->segmentPrefix != Reg_Invalid)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2469 stmt->error("too many segment prefixes");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2470 else if (i >= Reg_CS && i <= Reg_GS)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2471 operand->segmentPrefix = (Reg) i;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2472 else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2473 stmt->error("'%s' is not a segment register", ident->string);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2474 return parseAsmExp();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2475 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2476 return newRegExp( (Reg) i );
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2477 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2478 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2479 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2480 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2481
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2482 if (opTakesLabel()/*opInfo->takesLabel()*/ && e->op == TOKidentifier) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2483 // DMD uses labels secondarily to other symbols, so check
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2484 // if IdentifierExp::semantic won't find anything.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2485 Dsymbol *scopesym;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2486
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2487 if ( ! sc->search(stmt->loc, ident, & scopesym) )
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2488 return new DsymbolExp(stmt->loc,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2489 sc->func->searchLabel( ident ));
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2490 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2491
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2492 e = e->semantic(sc);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2493
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2494 // Special case for floating point constant declarations.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2495 if (e->op == TOKfloat64) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2496 Dsymbol * sym = sc->search(stmt->loc, ident, NULL);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2497 if ( sym ) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2498 VarDeclaration *v = sym->isVarDeclaration();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2499 if ( v ) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2500 Expression *ve = new VarExp(stmt->loc, v);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2501 ve->type = e->type;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2502 e = ve;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2503 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2504 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2505 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2506 return e;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2507 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2508 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2509 case TOKdollar:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2510 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2511 ident = Id::__dollar;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2512 goto do_dollar;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2513 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2514 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2515 invalidExpression();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2516 return Handled;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2517 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2518 return e;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2519 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2520
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2521 void doAlign() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2522 // .align bits vs. bytes...
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2523 // apparently a.out platforms use bits instead of bytes...
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2524
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2525 // parse primary: DMD allows 'MyAlign' (const int) but not '2+2'
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2526 // GAS is padding with NOPs last time I checked.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2527 Expression * e = parseAsmExp()->optimize(WANTvalue | WANTinterpret);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2528 integer_t align = e->toInteger();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2529
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2530 if (align >= 0) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2531 // %% is this printf portable?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2532 #ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2533 insnTemplate->printf(".balign\t%u", (unsigned) align);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2534 #else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2535 insnTemplate->printf(".align\t%u", (unsigned) align);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2536 #endif
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2537 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2538 stmt->error("alignment must be a power of 2");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2539 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2540
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2541 setAsmCode();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2542 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2543
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2544 void doEven() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2545 // .align for GAS is in bits, others probably use bytes..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2546 #ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2547 insnTemplate->writestring((char *) ".align\t2");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2548 #else
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2549 insnTemplate->writestring((char *) ".align\t2");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2550 #endif
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2551 setAsmCode();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2552 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2553
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2554 void doNaked() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2555 // %% can we assume sc->func != 0?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2556 sc->func->naked = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2557 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2558
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2559 void doData() {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2560 static const char * directives[] = { ".byte", ".short", ".long", ".long",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2561 "", "", "" };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2562 // FIXME
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2563 /*
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2564 machine_mode mode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2565
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2566 insnTemplate->writestring((char*) directives[op - Op_db]);
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
2567 insnTemplate->writebyte(' ');
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2568
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2569 do {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2570 // DMD is pretty strict here, not even constant expressions are allowed..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2571 switch (op) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2572 case Op_db:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2573 case Op_ds:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2574 case Op_di:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2575 case Op_dl:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2576 if (token->value == TOKint32v || token->value == TOKuns32v ||
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2577 token->value == TOKint64v || token->value == TOKuns64v) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2578 // As per usual with GNU, assume at least 32-bit host
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2579 if (op != Op_dl)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2580 insnTemplate->printf("%u", (d_uns32) token->uns64value);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2581 else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2582 // Output two .longS. GAS has .quad, but would have to rely on 'L' format ..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2583 // just need to use HOST_WIDE_INT_PRINT_DEC
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2584 insnTemplate->printf("%u,%u",
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2585 (d_uns32) token->uns64value, (d_uns32) (token->uns64value >> 32));
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2586 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2587 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2588 stmt->error("expected integer constant");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2589 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2590 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2591 case Op_df:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2592 mode = SFmode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2593 goto do_float;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2594 case Op_dd:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2595 mode = DFmode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2596 goto do_float;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2597 case Op_de:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2598 #ifndef TARGET_80387
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2599 #define XFmode TFmode
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2600 #endif
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2601 mode = XFmode; // not TFmode
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2602 // drop through
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2603 do_float:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2604 if (token->value == TOKfloat32v || token->value == TOKfloat64v ||
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2605 token->value == TOKfloat80v) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2606 long words[3];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2607 real_to_target(words, & token->float80value.rv(), mode);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2608 // don't use directives..., just use .long like GCC
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2609 insnTemplate->printf(".long\t%u", words[0]);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2610 if (mode != SFmode)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2611 insnTemplate->printf(",%u", words[1]);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2612 // DMD outputs 10 bytes, so we need to switch to .short here
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2613 if (mode == XFmode)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2614 insnTemplate->printf("\n\t.short\t%u", words[2]);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2615 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2616 stmt->error("expected float constant");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2617 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2618 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2619 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2620 abort();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2621 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2622
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2623 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2624 if (token->value == TOKcomma) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2625 insnTemplate->writebyte(',');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2626 nextToken();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2627 } else if (token->value == TOKeof) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2628 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2629 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2630 stmt->error("expected comma");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2631 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2632 } while (1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2633
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2634 setAsmCode();*/
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2635 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2636 };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2637
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2638 #if D_GCC_VER < 40
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2639 // struct rtx was modified for c++; this macro from rtl.h needs to
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2640 // be modified accordingly.
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2641 #undef XEXP
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2642 #define XEXP(RTX, N) (RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2643 #endif
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2644
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2645 // FIXME
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2646 #define HOST_WIDE_INT long
229
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
2647 bool getFrameRelativeValue(LLValue* decl, HOST_WIDE_INT * result)
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2648 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2649 // FIXME
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2650 // // Using this instead of DECL_RTL for struct args seems like a
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2651 // // good way to get hit by a truck because it may not agree with
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2652 // // non-asm access, but asm code wouldn't know what GCC does anyway. */
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2653 // rtx r = DECL_INCOMING_RTL(decl);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2654 // rtx e1, e2;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2655 //
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2656 // // Local variables don't have DECL_INCOMING_RTL
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2657 // if (r == NULL_RTX)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2658 // r = DECL_RTL(decl);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2659 //
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2660 // if (r != NULL_RTX && GET_CODE(r) == MEM /* && r->frame_related */ ) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2661 // r = XEXP(r, 0);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2662 // if (GET_CODE(r) == PLUS) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2663 // e1 = XEXP(r, 0);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2664 // e2 = XEXP(r, 1);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2665 // if (e1 == virtual_incoming_args_rtx && GET_CODE(e2) == CONST_INT) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2666 // *result = INTVAL(e2) + 8; // %% 8 is 32-bit specific...
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2667 // return true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2668 // } else if (e1 == virtual_stack_vars_rtx && GET_CODE(e2) == CONST_INT) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2669 // *result = INTVAL(e2); // %% 8 is 32-bit specific...
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2670 // return true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2671 // }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2672 // } else if (r == virtual_incoming_args_rtx) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2673 // *result = 8;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2674 // return true; // %% same as above
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2675 // }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2676 // // shouldn't have virtual_stack_vars_rtx by itself
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2677 // }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2678 //
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2679 return false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
2680 }