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