-
Notifications
You must be signed in to change notification settings - Fork 172
/
operations.h
244 lines (157 loc) · 8.06 KB
/
operations.h
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/* Copyright (c) 2008-2013, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_OPERATIONS_H
#define AVIAN_CODEGEN_ASSEMBLER_ARM_OPERATIONS_H
#include "registers.h"
namespace vm {
class System;
}
namespace avian {
namespace codegen {
namespace arm {
class Context;
// shortcut functions
inline int newTemp(Context* con) {
return con->client->acquireTemporary(GPR_MASK);
}
inline int newTemp(Context* con, unsigned mask) {
return con->client->acquireTemporary(mask);
}
inline void freeTemp(Context* con, int r) {
con->client->releaseTemporary(r);
}
inline int64_t getValue(lir::Constant* con) {
return con->value->value();
}
inline lir::Register makeTemp(Context* con) {
lir::Register tmp(newTemp(con));
return tmp;
}
inline lir::Register makeTemp64(Context* con) {
lir::Register tmp(newTemp(con), newTemp(con));
return tmp;
}
inline void freeTemp(Context* con, const lir::Register& tmp) {
if (tmp.low != lir::NoRegister) freeTemp(con, tmp.low);
if (tmp.high != lir::NoRegister) freeTemp(con, tmp.high);
}
void shiftLeftR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
void moveRR(Context* con, unsigned srcSize, lir::Register* src,
unsigned dstSize, lir::Register* dst);
void shiftLeftC(Context* con, unsigned size UNUSED, lir::Constant* a, lir::Register* b, lir::Register* t);
void shiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
void shiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, lir::Register* b, lir::Register* t);
void unsignedShiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
void unsignedShiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, lir::Register* b, lir::Register* t);
bool needJump(MyBlock* b);
unsigned padding(MyBlock* b, unsigned offset);
void resolve(MyBlock* b);
void jumpR(Context* con, unsigned size UNUSED, lir::Register* target);
void swapRR(Context* con, unsigned aSize, lir::Register* a,
unsigned bSize, lir::Register* b);
void moveRR(Context* con, unsigned srcSize, lir::Register* src,
unsigned dstSize, lir::Register* dst);
void moveZRR(Context* con, unsigned srcSize, lir::Register* src,
unsigned, lir::Register* dst);
void moveCR(Context* con, unsigned size, lir::Constant* src,
unsigned, lir::Register* dst);
void moveCR2(Context* con, unsigned size, lir::Constant* src,
lir::Register* dst, Promise* callOffset);
void moveCR(Context* con, unsigned size, lir::Constant* src,
unsigned, lir::Register* dst);
void addR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
void subR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
void addC(Context* con, unsigned size, lir::Constant* a,
lir::Register* b, lir::Register* dst);
void subC(Context* con, unsigned size, lir::Constant* a,
lir::Register* b, lir::Register* dst);
void multiplyR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
void floatAbsoluteRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b);
void floatNegateRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b);
void float2FloatRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b);
void float2IntRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b);
void int2FloatRR(Context* con, unsigned, lir::Register* a, unsigned size, lir::Register* b);
void floatSqrtRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b);
void floatAddR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
void floatSubtractR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
void floatMultiplyR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
void floatDivideR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
int normalize(Context* con, int offset, int index, unsigned scale,
bool* preserveIndex, bool* release);
void store(Context* con, unsigned size, lir::Register* src,
int base, int offset, int index, unsigned scale, bool preserveIndex);
void moveRM(Context* con, unsigned srcSize, lir::Register* src,
unsigned dstSize UNUSED, lir::Memory* dst);
void load(Context* con, unsigned srcSize, int base, int offset, int index,
unsigned scale, unsigned dstSize, lir::Register* dst,
bool preserveIndex, bool signExtend);
void moveMR(Context* con, unsigned srcSize, lir::Memory* src,
unsigned dstSize, lir::Register* dst);
void moveZMR(Context* con, unsigned srcSize, lir::Memory* src,
unsigned dstSize, lir::Register* dst);
void andR(Context* con, unsigned size, lir::Register* a,
lir::Register* b, lir::Register* dst);
void andC(Context* con, unsigned size, lir::Constant* a,
lir::Register* b, lir::Register* dst);
void orR(Context* con, unsigned size, lir::Register* a,
lir::Register* b, lir::Register* dst);
void xorR(Context* con, unsigned size, lir::Register* a,
lir::Register* b, lir::Register* dst);
void moveAR2(Context* con, unsigned srcSize, lir::Address* src,
unsigned dstSize, lir::Register* dst);
void moveAR(Context* con, unsigned srcSize, lir::Address* src,
unsigned dstSize, lir::Register* dst);
void compareRR(Context* con, unsigned aSize, lir::Register* a,
unsigned bSize UNUSED, lir::Register* b);
void compareCR(Context* con, unsigned aSize, lir::Constant* a,
unsigned bSize, lir::Register* b);
void compareCM(Context* con, unsigned aSize, lir::Constant* a,
unsigned bSize, lir::Memory* b);
void compareRM(Context* con, unsigned aSize, lir::Register* a,
unsigned bSize, lir::Memory* b);
int32_t
branch(Context* con, lir::TernaryOperation op);
void conditional(Context* con, int32_t branch, lir::Constant* target);
void branch(Context* con, lir::TernaryOperation op, lir::Constant* target);
void branchLong(Context* con, lir::TernaryOperation op, lir::Operand* al,
lir::Operand* ah, lir::Operand* bl,
lir::Operand* bh, lir::Constant* target,
BinaryOperationType compareSigned,
BinaryOperationType compareUnsigned);
void branchRR(Context* con, lir::TernaryOperation op, unsigned size,
lir::Register* a, lir::Register* b,
lir::Constant* target);
void branchCR(Context* con, lir::TernaryOperation op, unsigned size,
lir::Constant* a, lir::Register* b,
lir::Constant* target);
void branchRM(Context* con, lir::TernaryOperation op, unsigned size,
lir::Register* a, lir::Memory* b,
lir::Constant* target);
void branchCM(Context* con, lir::TernaryOperation op, unsigned size,
lir::Constant* a, lir::Memory* b,
lir::Constant* target);
ShiftMaskPromise*
shiftMaskPromise(Context* con, Promise* base, unsigned shift, int64_t mask);
void moveCM(Context* con, unsigned srcSize, lir::Constant* src,
unsigned dstSize, lir::Memory* dst);
void negateRR(Context* con, unsigned srcSize, lir::Register* src,
unsigned dstSize UNUSED, lir::Register* dst);
void callR(Context* con, unsigned size UNUSED, lir::Register* target);
void callC(Context* con, unsigned size UNUSED, lir::Constant* target);
void longCallC(Context* con, unsigned size UNUSED, lir::Constant* target);
void longJumpC(Context* con, unsigned size UNUSED, lir::Constant* target);
void jumpC(Context* con, unsigned size UNUSED, lir::Constant* target);
void return_(Context* con);
void trap(Context* con);
void loadBarrier(Context*);
void storeStoreBarrier(Context*);
void storeLoadBarrier(Context*);
} // namespace arm
} // namespace codegen
} // namespace avian
#endif // AVIAN_CODEGEN_ASSEMBLER_ARM_OPERATIONS_H