0
|
1 module dmd.backend.code;
|
|
2
|
|
3 import dmd.backend.targ_types;
|
|
4 import dmd.backend.Srcpos;
|
|
5 import dmd.backend.elem;
|
|
6 import dmd.backend.block;
|
|
7 import dmd.backend.Symbol;
|
|
8 import dmd.Declaration;
|
|
9 import dmd.LabelDsymbol;
|
|
10
|
|
11 /**********************************
|
|
12 * Code data type
|
|
13 */
|
|
14
|
|
15 union evc
|
|
16 {
|
|
17 targ_int Vint; // also used for tmp numbers (FLtmp)
|
|
18 targ_uns Vuns;
|
|
19 targ_long Vlong;
|
|
20
|
|
21 struct EP
|
|
22 {
|
|
23 targ_size_t Vpointer;
|
|
24 int Vseg; // segment the pointer is in
|
|
25 } EP _EP;
|
|
26
|
|
27 Srcpos Vsrcpos; // source position for OPlinnum
|
|
28 elem* Vtor; // OPctor/OPdtor elem
|
|
29 block* Vswitch; // when FLswitch and we have a switch table
|
|
30 code* Vcode; // when code is target of a jump (FLcode)
|
|
31 block* Vblock; // when block " (FLblock)
|
|
32
|
|
33 struct SP
|
|
34 {
|
|
35 targ_size_t Voffset; // offset from symbol
|
|
36 Symbol* Vsym; // pointer to symbol table (FLfunc,FLextern)
|
|
37 } SP sp;
|
|
38
|
|
39 version (MARS) {
|
|
40 struct DSP
|
|
41 {
|
|
42 targ_size_t Voffset; // offset from symbol
|
|
43 Declaration Vsym; // pointer to D symbol table
|
|
44 } DSP dsp;
|
|
45 }
|
|
46
|
|
47 version (MARS) {
|
|
48 struct LAB
|
|
49 {
|
|
50 targ_size_t Voffset; // offset from symbol
|
|
51 LabelDsymbol Vsym; // pointer to Label
|
|
52 } LAB lab;
|
|
53 }
|
|
54
|
|
55 struct AS
|
|
56 {
|
|
57 uint len;
|
|
58 char* bytes;
|
|
59 } AS as; // asm node (FLasm)
|
|
60 }
|
|
61
|
|
62 enum CF
|
|
63 {
|
|
64 CFes = 1, // generate an ES: segment override for this instr
|
|
65 CFjmp16 = 2, // need 16 bit jump offset (long branch)
|
|
66 CFtarg = 4, // this code is the target of a jump
|
|
67 CFseg = 8, // get segment of immediate value
|
|
68 CFoff = 0x10, // get offset of immediate value
|
|
69 CFss = 0x20, // generate an SS: segment override (not with
|
|
70 // CFes at the same time, though!)
|
|
71 CFpsw = 0x40, // we need the flags result after this instruction
|
|
72 CFopsize = 0x80, // prefix with operand size
|
|
73 CFaddrsize = 0x100, // prefix with address size
|
|
74 CFds = 0x200, // need DS override (not with es, ss, or cs )
|
|
75 CFcs = 0x400, // need CS override
|
|
76 CFfs = 0x800, // need FS override
|
|
77 CFgs = (CFcs | CFfs), // need GS override
|
|
78 CFwait = 0x1000, // If I32 it indicates when to output a WAIT
|
|
79 CFselfrel = 0x2000, // if self-relative
|
|
80 CFunambig = 0x4000, // indicates cannot be accessed by other addressing
|
|
81 // modes
|
|
82 CFtarg2 = 0x8000, // like CFtarg, but we can't optimize this away
|
|
83 CFvolatile = 0x10000, // volatile reference, do not schedule
|
|
84 CFclassinit= 0x20000, // class init code
|
|
85
|
|
86 CFSEG = (CFes | CFss | CFds | CFcs | CFfs | CFgs),
|
|
87 CFPREFIX = (CFSEG | CFopsize | CFaddrsize),
|
|
88 }
|
|
89
|
|
90 struct code
|
|
91 {
|
|
92 code* next;
|
|
93 uint Iflags;
|
|
94
|
|
95 ubyte Ijty = 0; // type of operand, 0 if unknown
|
|
96
|
|
97 ubyte Iop;
|
|
98 ubyte Irm; // reg/mode
|
|
99
|
|
100 ubyte Iop2; // second opcode byte
|
|
101 ubyte Isib = 0; // SIB byte
|
|
102
|
|
103 ubyte Iop3; // third opcode byte
|
|
104
|
|
105 ubyte IFL1;
|
|
106 ubyte IFL2; // FLavors of 1st, 2nd operands
|
|
107 evc IEV1; // 1st operand, if any
|
|
108
|
|
109 ref targ_size_t IEVpointer1 () { return IEV1._EP.Vpointer; }
|
|
110 ref int IEVseg1 () { return IEV1._EP.Vseg; }
|
|
111 ref Symbol* IEVsym1 () { return IEV1.sp.Vsym; }
|
|
112 ref Declaration IEVdsym1 () { return IEV1.dsp.Vsym; }
|
|
113 ref targ_size_t IEVoffset1 () { return IEV1.sp.Voffset; }
|
|
114 ref LabelDsymbol IEVlsym1 () { return IEV1.lab.Vsym; }
|
|
115 ref targ_int IEVint1 () { return IEV1.Vint; }
|
|
116
|
|
117 evc IEV2; // 2nd operand, if any
|
|
118
|
|
119 ref targ_size_t IEVpointer2 () { return IEV2._EP.Vpointer; }
|
|
120 ref int IEVseg2 () { return IEV2._EP.Vseg; }
|
|
121 ref Symbol* IEVsym2 () { return IEV2.sp.Vsym; }
|
|
122 ref Declaration IEVdsym2 () { return IEV2.dsp.Vsym; }
|
|
123 ref targ_size_t IEVoffset2 () { return IEV2.sp.Voffset; }
|
|
124 ref LabelDsymbol IEVlsym2 () { return IEV2.lab.Vsym; }
|
|
125 ref targ_int IEVint2 () { return IEV2.Vint; }
|
|
126 /+
|
|
127 void print(); // pretty-printer
|
|
128 +/
|
|
129 }
|
|
130
|
|
131 import std.stdio;
|
|
132
|
|
133 void dumpCode(code* foo)
|
|
134 {
|
|
135 writefln("code.sizeof: %d", code.sizeof);
|
|
136 writefln("Srcpos.sizeof: %d", Srcpos.sizeof);
|
|
137 writefln("evc.sizeof: %d", evc.sizeof);
|
|
138 writefln("EP.sizeof: %d", evc.EP.sizeof);
|
|
139 writefln("SP.sizeof: %d", evc.SP.sizeof);
|
|
140 writefln("targ_long.sizeof: %d", targ_long.sizeof);
|
|
141 foreach (a, b; foo.tupleof)
|
|
142 {
|
34
|
143 ///std.stdio.writeln(foo.tupleof[a].stringof, " ", cast(char*)&foo.tupleof[a] - cast(char*)foo, " = ", foo.tupleof[a]);
|
0
|
144 //std.stdio.writeln("printf(\"", foo.tupleof[a].stringof, " %d = %d\\n\",(char*)(&", foo.tupleof[a].stringof, ")-(char*)foo, ", foo.tupleof[a].stringof, ");");
|
|
145 }
|
|
146 } |