File: InstrFwd.h

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (181 lines) | stat: -rw-r--r-- 5,593 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#pragma once

namespace code {

	/**
	 * Make these functions more convenient to call in C++ during certain conditions:
	 *
	 * It inhibits the clarity and it is a bit annoying to have to do:
	 * *foo << mov(e, eax, ebx);
	 *
	 * instead of:
	 * *foo << mov(eax, ebx);
	 *
	 * The first engine parameter is not visible in Storm (as it will insert that for us
	 * automatically), but in C++ we need another mechanism as C++ does not know which engine we
	 * will use. So in the context of directly appending instructions to a Listing object, we can
	 * save the parameters in some container temporarily and delay the call to the actual creating
	 * function until the result is appended to a Listing. When this happens, we can get an Engine
	 * from there and create the Instr object properly. This is done with the template magic
	 * below. Sadly, we need to declare all machine operations once more at the end, but that is a
	 * small price to pay.
	 */

	template <Instr *(*Fn)(EnginePtr)>
	class InstrProxy0 {};

	template <Instr *(*Fn)(EnginePtr)>
	inline Listing &operator <<(Listing &l, const InstrProxy0<Fn> &p) {
		return l << (*Fn)(l.engine());
	}


	template <class T, Instr *(*Fn)(EnginePtr, T)>
	class InstrProxy1 {
	public:
		const T &t;
		InstrProxy1(const T &t) : t(t) {}
	};

	template <class T, Instr *(*Fn)(EnginePtr, T)>
	inline Listing &operator <<(Listing &l, const InstrProxy1<T, Fn> &p) {
		return l << (*Fn)(l.engine(), p.t);
	}


	template <class T, class U, Instr *(*Fn)(EnginePtr, T, U)>
	class InstrProxy2 {
	public:
		const T &t;
		const U &u;
		InstrProxy2(const T &t, const U &u) : t(t), u(u) {}
	};

	template <class T, class U, Instr *(*Fn)(EnginePtr, T, U)>
	inline Listing &operator <<(Listing &l, const InstrProxy2<T, U, Fn> &p) {
		return l << (*Fn)(l.engine(), p.t, p.u);
	}


	template <class T, class U, class V, Instr *(*Fn)(EnginePtr, T, U, V)>
	class InstrProxy3 {
	public:
		const T &t;
		const U &u;
		const V &v;
		InstrProxy3(const T &t, const U &u, const V &v) : t(t), u(u), v(v) {}
	};

	template <class T, class U, class V, Instr *(*Fn)(EnginePtr, T, U, V)>
	inline Listing &operator <<(Listing &l, const InstrProxy3<T, U, V, Fn> &p) {
		return l << (*Fn)(l.engine(), p.t, p.u, p.v);
	}

	template <class T, class U, class V, class W, Instr *(*Fn)(EnginePtr, T, U, V, W)>
	class InstrProxy4 {
	public:
		const T &t;
		const U &u;
		const V &v;
		const W &w;
		InstrProxy4(const T &t, const U &u, const V &v, const W &w) : t(t), u(u), v(v), w(w) {}
	};

	template <class T, class U, class V, class W, Instr *(*Fn)(EnginePtr, T, U, V, W)>
	inline Listing &operator <<(Listing &l, const InstrProxy4<T, U, V, W, Fn> &p) {
		return l << (*Fn)(l.engine(), p.t, p.u, p.v, p.w);
	}


#define PROXY0(op)												\
	inline InstrProxy0<&op> op() {								\
		return InstrProxy0<&op>();								\
	}
#define PROXY1(op, T)													\
	inline InstrProxy1<T, &op> op(T const &t) {							\
		return InstrProxy1<T, &op>(t);									\
	}
#define PROXY2(op, T, U)												\
	inline InstrProxy2<T, U, &op> op(T const &t, U const &u) {			\
		return InstrProxy2<T, U, &op>(t, u);							\
	}
#define PROXY3(op, T, U, V)												\
	inline InstrProxy3<T, U, V, &op> op(T const &t, U const &u, V const &v) { \
		return InstrProxy3<T, U, V, &op>(t, u, v);						\
	}
#define PROXY4(op, T, U, V, W)											\
	inline InstrProxy4<T, U, V, W, &op> op(T const &t, U const &u, V const &v, W const &w) { \
		return InstrProxy4<T, U, V, W, &op>(t, u, v, w);				\
	}

	// Repetition of all OP-codes.
	PROXY0(nop);
	PROXY2(mov, Operand, Operand);
	PROXY2(swap, Reg, Operand);
	PROXY1(push, Operand);
	PROXY1(pop, Operand);
	PROXY0(pushFlags);
	PROXY0(popFlags);
	PROXY1(jmp, Operand);
	PROXY2(jmp, Label, CondFlag);
	PROXY2(call, Operand, Size);
	PROXY1(ret, Size);
	PROXY2(lea, Operand, Operand);
	PROXY2(setCond, Operand, CondFlag);
	PROXY2(fnParam, TypeDesc *, Operand);
	PROXY2(fnParamRef, TypeDesc *, Operand);
	PROXY2(fnCall, Operand, Bool);
	PROXY4(fnCall, Operand, Bool, TypeDesc *, Operand);
	PROXY4(fnCallRef, Operand, Bool, TypeDesc *, Operand);
	PROXY1(fnRet, Operand);
	PROXY1(fnRetRef, Operand);
	PROXY0(fnRet);
	PROXY2(bor, Operand, Operand);
	PROXY2(band, Operand, Operand);
	PROXY2(bxor, Operand, Operand);
	PROXY1(bnot, Operand);
	PROXY2(test, Operand, Operand);
	PROXY2(add, Operand, Operand);
	PROXY2(adc, Operand, Operand);
	PROXY2(sub, Operand, Operand);
	PROXY2(sbb, Operand, Operand);
	PROXY2(cmp, Operand, Operand);
	PROXY2(mul, Operand, Operand);
	PROXY2(idiv, Operand, Operand);
	PROXY2(imod, Operand, Operand);
	PROXY2(udiv, Operand, Operand);
	PROXY2(umod, Operand, Operand);
	PROXY2(shl, Operand, Operand);
	PROXY2(shr, Operand, Operand);
	PROXY2(sar, Operand, Operand);
	PROXY2(icast, Operand, Operand);
	PROXY2(ucast, Operand, Operand);
	PROXY2(fadd, Operand, Operand);
	PROXY2(fsub, Operand, Operand);
	PROXY2(fneg, Operand, Operand);
	PROXY2(fmul, Operand, Operand);
	PROXY2(fdiv, Operand, Operand);
	PROXY2(fcmp, Operand, Operand);
	PROXY2(fcast, Operand, Operand);
	PROXY2(fcasti, Operand, Operand);
	PROXY2(fcastu, Operand, Operand);
	PROXY2(icastf, Operand, Operand);
	PROXY2(ucastf, Operand, Operand);
	PROXY1(fstp, Operand);
	PROXY1(fld, Operand);
	PROXY1(dat, Operand);
	PROXY1(lblOffset, Label);
	PROXY1(align, Offset);
	PROXY1(alignAs, Size);
	PROXY0(prolog);
	PROXY0(epilog);
	PROXY2(shadowMov, Operand, Operand);
	PROXY2(preserve, Operand, Reg);
	PROXY1(preserve, Reg);
	PROXY1(location, SrcPos);
	PROXY1(begin, Block);
	PROXY1(end, Block);
	PROXY2(jmpBlock, Label, Block);
	PROXY1(activate, Var);
	PROXY0(threadLocal);
}