Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/cpu/arm/assembler_arm.hpp
40930 views
1
/*
2
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#ifndef CPU_ARM_ASSEMBLER_ARM_HPP
26
#define CPU_ARM_ASSEMBLER_ARM_HPP
27
28
#include "utilities/macros.hpp"
29
30
enum AsmCondition {
31
eq, ne, cs, cc, mi, pl, vs, vc,
32
hi, ls, ge, lt, gt, le, al, nv,
33
number_of_conditions,
34
// alternative names
35
hs = cs,
36
lo = cc
37
};
38
39
enum AsmShift {
40
lsl, lsr, asr, ror
41
};
42
43
44
enum AsmOffset {
45
basic_offset = 1 << 24,
46
pre_indexed = 1 << 24 | 1 << 21,
47
post_indexed = 0
48
};
49
50
51
enum AsmWriteback {
52
no_writeback,
53
writeback
54
};
55
56
enum AsmOffsetOp {
57
sub_offset = 0,
58
add_offset = 1
59
};
60
61
62
// ARM Addressing Modes 2 and 3 - Load and store
63
class Address {
64
private:
65
Register _base;
66
Register _index;
67
int _disp;
68
AsmOffset _mode;
69
RelocationHolder _rspec;
70
int _shift_imm;
71
AsmShift _shift;
72
AsmOffsetOp _offset_op;
73
74
static inline int abs(int x) { return x < 0 ? -x : x; }
75
static inline int up (int x) { return x < 0 ? 0 : 1; }
76
77
static const AsmShift LSL = lsl;
78
79
public:
80
Address() : _base(noreg) {}
81
82
Address(Register rn, int offset = 0, AsmOffset mode = basic_offset) {
83
_base = rn;
84
_index = noreg;
85
_disp = offset;
86
_mode = mode;
87
_shift_imm = 0;
88
_shift = lsl;
89
_offset_op = add_offset;
90
}
91
92
Address(Register rn, ByteSize offset, AsmOffset mode = basic_offset) :
93
Address(rn, in_bytes(offset), mode) {}
94
95
Address(Register rn, Register rm, AsmShift shift = lsl,
96
int shift_imm = 0, AsmOffset mode = basic_offset,
97
AsmOffsetOp offset_op = add_offset) {
98
_base = rn;
99
_index = rm;
100
_disp = 0;
101
_shift = shift;
102
_shift_imm = shift_imm;
103
_mode = mode;
104
_offset_op = offset_op;
105
}
106
107
Address(Register rn, RegisterOrConstant offset, AsmShift shift = lsl,
108
int shift_imm = 0) {
109
_base = rn;
110
if (offset.is_constant()) {
111
_index = noreg;
112
{
113
int off = (int) offset.as_constant();
114
if (shift_imm != 0) {
115
assert(shift == lsl,"shift not yet encoded");
116
off = off << shift_imm;
117
}
118
_disp = off;
119
}
120
_shift = lsl;
121
_shift_imm = 0;
122
} else {
123
_index = offset.as_register();
124
_disp = 0;
125
_shift = shift;
126
_shift_imm = shift_imm;
127
}
128
_mode = basic_offset;
129
_offset_op = add_offset;
130
}
131
132
// [base + index * wordSize]
133
static Address indexed_ptr(Register base, Register index) {
134
return Address(base, index, LSL, LogBytesPerWord);
135
}
136
137
// [base + index * BytesPerInt]
138
static Address indexed_32(Register base, Register index) {
139
return Address(base, index, LSL, LogBytesPerInt);
140
}
141
142
// [base + index * BytesPerHeapOop]
143
static Address indexed_oop(Register base, Register index) {
144
return Address(base, index, LSL, LogBytesPerHeapOop);
145
}
146
147
Address plus_disp(int disp) const {
148
assert((disp == 0) || (_index == noreg),"can't apply an offset to a register indexed address");
149
Address a = (*this);
150
a._disp += disp;
151
return a;
152
}
153
154
Address rebase(Register new_base) const {
155
Address a = (*this);
156
a._base = new_base;
157
return a;
158
}
159
160
int encoding2() const {
161
assert(_mode == basic_offset || _base != PC, "unpredictable instruction");
162
if (_index == noreg) {
163
assert(-4096 < _disp && _disp < 4096, "encoding constraint");
164
return _mode | up(_disp) << 23 | _base->encoding() << 16 | abs(_disp);
165
} else {
166
assert(_index != PC && (_mode == basic_offset || _index != _base), "unpredictable instruction");
167
assert(_disp == 0 && (_shift_imm >> 5) == 0, "encoding constraint");
168
return 1 << 25 | _offset_op << 23 | _mode | _base->encoding() << 16 |
169
_shift_imm << 7 | _shift << 5 | _index->encoding();
170
}
171
}
172
173
int encoding3() const {
174
assert(_mode == basic_offset || _base != PC, "unpredictable instruction");
175
if (_index == noreg) {
176
assert(-256 < _disp && _disp < 256, "encoding constraint");
177
return _mode | up(_disp) << 23 | 1 << 22 | _base->encoding() << 16 |
178
(abs(_disp) & 0xf0) << 4 | abs(_disp) & 0x0f;
179
} else {
180
assert(_index != PC && (_mode == basic_offset || _index != _base), "unpredictable instruction");
181
assert(_disp == 0 && _shift == lsl && _shift_imm == 0, "encoding constraint");
182
return _mode | _offset_op << 23 | _base->encoding() << 16 | _index->encoding();
183
}
184
}
185
186
int encoding_ex() const {
187
assert(_index == noreg && _disp == 0 && _mode == basic_offset &&
188
_base != PC, "encoding constraint");
189
return _base->encoding() << 16;
190
}
191
192
int encoding_vfp() const {
193
assert(_index == noreg && _mode == basic_offset, "encoding constraint");
194
assert(-1024 < _disp && _disp < 1024 && (_disp & 3) == 0, "encoding constraint");
195
return _base->encoding() << 16 | up(_disp) << 23 | abs(_disp) >> 2;
196
}
197
198
int encoding_simd() const {
199
assert(_base != PC, "encoding constraint");
200
assert(_index != PC && _index != SP, "encoding constraint");
201
assert(_disp == 0, "encoding constraint");
202
assert(_shift == 0, "encoding constraint");
203
assert(_index == noreg || _mode == basic_offset, "encoding constraint");
204
assert(_mode == basic_offset || _mode == post_indexed, "encoding constraint");
205
int index;
206
if (_index == noreg) {
207
if (_mode == post_indexed)
208
index = 13;
209
else
210
index = 15;
211
} else {
212
index = _index->encoding();
213
}
214
215
return _base->encoding() << 16 | index;
216
}
217
218
Register base() const {
219
return _base;
220
}
221
222
Register index() const {
223
return _index;
224
}
225
226
int disp() const {
227
return _disp;
228
}
229
230
AsmOffset mode() const {
231
return _mode;
232
}
233
234
int shift_imm() const {
235
return _shift_imm;
236
}
237
238
AsmShift shift() const {
239
return _shift;
240
}
241
242
AsmOffsetOp offset_op() const {
243
return _offset_op;
244
}
245
246
bool uses(Register reg) const { return _base == reg || _index == reg; }
247
248
const relocInfo::relocType rtype() { return _rspec.type(); }
249
const RelocationHolder& rspec() { return _rspec; }
250
251
// Convert the raw encoding form into the form expected by the
252
// constructor for Address.
253
static Address make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc);
254
};
255
256
#ifdef COMPILER2
257
class VFP {
258
// Helper classes to detect whether a floating point constant can be
259
// encoded in a fconstd or fconsts instruction
260
// The conversion from the imm8, 8 bit constant, to the floating
261
// point value encoding is done with either:
262
// for single precision: imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5):imm8<5:0>:Zeros(19)
263
// or
264
// for double precision: imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8):imm8<5:0>:Zeros(48)
265
266
private:
267
class fpnum {
268
public:
269
virtual unsigned int f_hi4() const = 0;
270
virtual bool f_lo_is_null() const = 0;
271
virtual int e() const = 0;
272
virtual unsigned int s() const = 0;
273
274
inline bool can_be_imm8() const { return e() >= -3 && e() <= 4 && f_lo_is_null(); }
275
inline unsigned char imm8() const { int v = (s() << 7) | (((e() - 1) & 0x7) << 4) | f_hi4(); assert((v >> 8) == 0, "overflow"); return v; }
276
};
277
278
public:
279
class float_num : public fpnum {
280
public:
281
float_num(float v) {
282
_num.val = v;
283
}
284
285
virtual unsigned int f_hi4() const { return (_num.bits << 9) >> (19+9); }
286
virtual bool f_lo_is_null() const { return (_num.bits & ((1 << 19) - 1)) == 0; }
287
virtual int e() const { return ((_num.bits << 1) >> (23+1)) - 127; }
288
virtual unsigned int s() const { return _num.bits >> 31; }
289
290
private:
291
union {
292
float val;
293
unsigned int bits;
294
} _num;
295
};
296
297
class double_num : public fpnum {
298
public:
299
double_num(double v) {
300
_num.val = v;
301
}
302
303
virtual unsigned int f_hi4() const { return (_num.bits << 12) >> (48+12); }
304
virtual bool f_lo_is_null() const { return (_num.bits & ((1LL << 48) - 1)) == 0; }
305
virtual int e() const { return ((_num.bits << 1) >> (52+1)) - 1023; }
306
virtual unsigned int s() const { return _num.bits >> 63; }
307
308
private:
309
union {
310
double val;
311
unsigned long long bits;
312
} _num;
313
};
314
};
315
#endif
316
317
#include "assembler_arm_32.hpp"
318
319
320
#endif // CPU_ARM_ASSEMBLER_ARM_HPP
321
322