Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(585)

Side by Side Diff: src/a64/instructions-a64.h

Issue 144963003: A64: add missing files. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/a64/ic-a64.cc ('k') | src/a64/instructions-a64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_A64_INSTRUCTIONS_A64_H_
29 #define V8_A64_INSTRUCTIONS_A64_H_
30
31 #include "globals.h"
32 #include "utils.h"
33 #include "a64/constants-a64.h"
34 #include "a64/utils-a64.h"
35
36 namespace v8 {
37 namespace internal {
38
39
40 // ISA constants. --------------------------------------------------------------
41
42 typedef uint32_t Instr;
43 const float kFP32PositiveInfinity = rawbits_to_float(0x7f800000);
44 const float kFP32NegativeInfinity = rawbits_to_float(0xff800000);
45 const double kFP64PositiveInfinity = rawbits_to_double(0x7ff0000000000000UL);
46 const double kFP64NegativeInfinity = rawbits_to_double(0xfff0000000000000UL);
47
48 // This value is a signalling NaN as both a double and as a float (taking the
49 // least-significant word).
50 static const double kFP64SignallingNaN = rawbits_to_double(0x7ff000007f800001);
51 static const float kFP32SignallingNaN = rawbits_to_float(0x7f800001);
52
53 // A similar value, but as a quiet NaN.
54 static const double kFP64QuietNaN = rawbits_to_double(0x7ff800007fc00001);
55 static const float kFP32QuietNaN = rawbits_to_float(0x7fc00001);
56
57
58 enum LSDataSize {
59 LSByte = 0,
60 LSHalfword = 1,
61 LSWord = 2,
62 LSDoubleWord = 3
63 };
64
65 LSDataSize CalcLSPairDataSize(LoadStorePairOp op);
66
67 enum ImmBranchType {
68 UnknownBranchType = 0,
69 CondBranchType = 1,
70 UncondBranchType = 2,
71 CompareBranchType = 3,
72 TestBranchType = 4
73 };
74
75 enum AddrMode {
76 Offset,
77 PreIndex,
78 PostIndex
79 };
80
81 enum FPRounding {
82 // The first four values are encodable directly by FPCR<RMode>.
83 FPTieEven = 0x0,
84 FPPositiveInfinity = 0x1,
85 FPNegativeInfinity = 0x2,
86 FPZero = 0x3,
87
88 // The final rounding mode is only available when explicitly specified by the
89 // instruction (such as with fcvta). It cannot be set in FPCR.
90 FPTieAway
91 };
92
93 enum Reg31Mode {
94 Reg31IsStackPointer,
95 Reg31IsZeroRegister
96 };
97
98 // Instructions. ---------------------------------------------------------------
99
100 class Instruction {
101 public:
102 inline Instr InstructionBits() const {
103 Instr bits;
104 memcpy(&bits, this, sizeof(bits));
105 return bits;
106 }
107
108 inline void SetInstructionBits(Instr new_instr) {
109 memcpy(this, &new_instr, sizeof(new_instr));
110 }
111
112 inline int Bit(int pos) const {
113 return (InstructionBits() >> pos) & 1;
114 }
115
116 inline uint32_t Bits(int msb, int lsb) const {
117 return unsigned_bitextract_32(msb, lsb, InstructionBits());
118 }
119
120 inline int32_t SignedBits(int msb, int lsb) const {
121 int32_t bits = *(reinterpret_cast<const int32_t*>(this));
122 return signed_bitextract_32(msb, lsb, bits);
123 }
124
125 inline Instr Mask(uint32_t mask) const {
126 return InstructionBits() & mask;
127 }
128
129 inline Instruction* following(int count = 1) {
130 return this + count * kInstructionSize;
131 }
132
133 inline Instruction* preceding(int count = 1) {
134 return this - count * kInstructionSize;
135 }
136
137 #define DEFINE_GETTER(Name, HighBit, LowBit, Func) \
138 inline int64_t Name() const { return Func(HighBit, LowBit); }
139 INSTRUCTION_FIELDS_LIST(DEFINE_GETTER)
140 #undef DEFINE_GETTER
141
142 // ImmPCRel is a compound field (not present in INSTRUCTION_FIELDS_LIST),
143 // formed from ImmPCRelLo and ImmPCRelHi.
144 int ImmPCRel() const {
145 int const offset = ((ImmPCRelHi() << ImmPCRelLo_width) | ImmPCRelLo());
146 int const width = ImmPCRelLo_width + ImmPCRelHi_width;
147 return signed_bitextract_32(width-1, 0, offset);
148 }
149
150 uint64_t ImmLogical();
151 float ImmFP32();
152 double ImmFP64();
153
154 inline LSDataSize SizeLSPair() const {
155 return CalcLSPairDataSize(
156 static_cast<LoadStorePairOp>(Mask(LoadStorePairMask)));
157 }
158
159 // Helpers.
160 inline bool IsCondBranchImm() const {
161 return Mask(ConditionalBranchFMask) == ConditionalBranchFixed;
162 }
163
164 inline bool IsUncondBranchImm() const {
165 return Mask(UnconditionalBranchFMask) == UnconditionalBranchFixed;
166 }
167
168 inline bool IsCompareBranch() const {
169 return Mask(CompareBranchFMask) == CompareBranchFixed;
170 }
171
172 inline bool IsTestBranch() const {
173 return Mask(TestBranchFMask) == TestBranchFixed;
174 }
175
176 inline bool IsLdrLiteral() const {
177 return Mask(LoadLiteralFMask) == LoadLiteralFixed;
178 }
179
180 inline bool IsLdrLiteralX() const {
181 return Mask(LoadLiteralMask) == LDR_x_lit;
182 }
183
184 inline bool IsPCRelAddressing() const {
185 return Mask(PCRelAddressingFMask) == PCRelAddressingFixed;
186 }
187
188 inline bool IsLogicalImmediate() const {
189 return Mask(LogicalImmediateFMask) == LogicalImmediateFixed;
190 }
191
192 inline bool IsAddSubImmediate() const {
193 return Mask(AddSubImmediateFMask) == AddSubImmediateFixed;
194 }
195
196 inline bool IsAddSubExtended() const {
197 return Mask(AddSubExtendedFMask) == AddSubExtendedFixed;
198 }
199
200 inline bool IsLoadOrStore() const {
201 return Mask(LoadStoreAnyFMask) == LoadStoreAnyFixed;
202 }
203
204 // Indicate whether Rd can be the stack pointer or the zero register. This
205 // does not check that the instruction actually has an Rd field.
206 inline Reg31Mode RdMode() const {
207 // The following instructions use csp or wsp as Rd:
208 // Add/sub (immediate) when not setting the flags.
209 // Add/sub (extended) when not setting the flags.
210 // Logical (immediate) when not setting the flags.
211 // Otherwise, r31 is the zero register.
212 if (IsAddSubImmediate() || IsAddSubExtended()) {
213 if (Mask(AddSubSetFlagsBit)) {
214 return Reg31IsZeroRegister;
215 } else {
216 return Reg31IsStackPointer;
217 }
218 }
219 if (IsLogicalImmediate()) {
220 // Of the logical (immediate) instructions, only ANDS (and its aliases)
221 // can set the flags. The others can all write into csp.
222 // Note that some logical operations are not available to
223 // immediate-operand instructions, so we have to combine two masks here.
224 if (Mask(LogicalImmediateMask & LogicalOpMask) == ANDS) {
225 return Reg31IsZeroRegister;
226 } else {
227 return Reg31IsStackPointer;
228 }
229 }
230 return Reg31IsZeroRegister;
231 }
232
233 // Indicate whether Rn can be the stack pointer or the zero register. This
234 // does not check that the instruction actually has an Rn field.
235 inline Reg31Mode RnMode() const {
236 // The following instructions use csp or wsp as Rn:
237 // All loads and stores.
238 // Add/sub (immediate).
239 // Add/sub (extended).
240 // Otherwise, r31 is the zero register.
241 if (IsLoadOrStore() || IsAddSubImmediate() || IsAddSubExtended()) {
242 return Reg31IsStackPointer;
243 }
244 return Reg31IsZeroRegister;
245 }
246
247 inline ImmBranchType BranchType() const {
248 if (IsCondBranchImm()) {
249 return CondBranchType;
250 } else if (IsUncondBranchImm()) {
251 return UncondBranchType;
252 } else if (IsCompareBranch()) {
253 return CompareBranchType;
254 } else if (IsTestBranch()) {
255 return TestBranchType;
256 } else {
257 return UnknownBranchType;
258 }
259 }
260
261 inline bool IsBranchAndLinkToRegister() const {
262 return Mask(UnconditionalBranchToRegisterMask) == BLR;
263 }
264
265 inline bool IsMovz() const {
266 return (Mask(MoveWideImmediateMask) == MOVZ_x) ||
267 (Mask(MoveWideImmediateMask) == MOVZ_w);
268 }
269
270 inline bool IsMovk() const {
271 return (Mask(MoveWideImmediateMask) == MOVK_x) ||
272 (Mask(MoveWideImmediateMask) == MOVK_w);
273 }
274
275 inline bool IsMovn() const {
276 return (Mask(MoveWideImmediateMask) == MOVN_x) ||
277 (Mask(MoveWideImmediateMask) == MOVN_w);
278 }
279
280 inline bool IsNop(int n) {
281 // A marking nop is an instruction
282 // mov r<n>, r<n>
283 // which is encoded as
284 // orr r<n>, xzr, r<n>
285 return (Mask(LogicalShiftedMask) == ORR_x) &&
286 (Rd() == Rm()) &&
287 (Rd() == n);
288 }
289
290 // Find the PC offset encoded in this instruction. 'this' may be a branch or
291 // a PC-relative addressing instruction.
292 // The offset returned is unscaled.
293 ptrdiff_t ImmPCOffset();
294
295 // Find the target of this instruction. 'this' may be a branch or a
296 // PC-relative addressing instruction.
297 Instruction* ImmPCOffsetTarget();
298
299 // Patch a PC-relative offset to refer to 'target'. 'this' may be a branch or
300 // a PC-relative addressing instruction.
301 void SetImmPCOffsetTarget(Instruction* target);
302 // Patch a literal load instruction to load from 'source'.
303 void SetImmLLiteral(Instruction* source);
304
305 inline uint8_t* LiteralAddress() {
306 int offset = ImmLLiteral() << kLiteralEntrySizeLog2;
307 return reinterpret_cast<uint8_t*>(this) + offset;
308 }
309
310 inline uint32_t Literal32() {
311 uint32_t literal;
312 memcpy(&literal, LiteralAddress(), sizeof(literal));
313
314 return literal;
315 }
316
317 inline uint64_t Literal64() {
318 uint64_t literal;
319 memcpy(&literal, LiteralAddress(), sizeof(literal));
320
321 return literal;
322 }
323
324 inline float LiteralFP32() {
325 return rawbits_to_float(Literal32());
326 }
327
328 inline double LiteralFP64() {
329 return rawbits_to_double(Literal64());
330 }
331
332 inline Instruction* NextInstruction() {
333 return this + kInstructionSize;
334 }
335
336 inline Instruction* InstructionAtOffset(int64_t offset) {
337 ASSERT(IsAligned(reinterpret_cast<uintptr_t>(this) + offset,
338 kInstructionSize));
339 return this + offset;
340 }
341
342 template<typename T> static inline Instruction* Cast(T src) {
343 return reinterpret_cast<Instruction*>(src);
344 }
345
346 private:
347 inline int ImmBranch() const;
348
349 void SetPCRelImmTarget(Instruction* target);
350 void SetBranchImmTarget(Instruction* target);
351 };
352
353
354 // Where Instruction looks at instructions generated by the Assembler,
355 // InstructionSequence looks at instructions sequences generated by the
356 // MacroAssembler.
357 class InstructionSequence : public Instruction {
358 public:
359 static InstructionSequence* At(Address address) {
360 return reinterpret_cast<InstructionSequence*>(address);
361 }
362
363 // Sequences generated by MacroAssembler::InlineData().
364 bool IsInlineData() const;
365 uint64_t InlineData() const;
366 };
367
368
369 // Simulator/Debugger debug instructions ---------------------------------------
370 // Each debug marker is represented by a HLT instruction. The immediate comment
371 // field in the instruction is used to identify the type of debug marker. Each
372 // marker encodes arguments in a different way, as described below.
373
374 // Indicate to the Debugger that the instruction is a redirected call.
375 const Instr kImmExceptionIsRedirectedCall = 0xca11;
376
377 // Represent unreachable code. This is used as a guard in parts of the code that
378 // should not be reachable, such as in data encoded inline in the instructions.
379 const Instr kImmExceptionIsUnreachable = 0xdebf;
380
381 // A pseudo 'printf' instruction. The arguments will be passed to the platform
382 // printf method.
383 const Instr kImmExceptionIsPrintf = 0xdeb1;
384 // Parameters are stored in A64 registers as if the printf pseudo-instruction
385 // was a call to the real printf method:
386 //
387 // x0: The format string, then either of:
388 // x1-x7: Optional arguments.
389 // d0-d7: Optional arguments.
390 //
391 // Floating-point and integer arguments are passed in separate sets of
392 // registers in AAPCS64 (even for varargs functions), so it is not possible to
393 // determine the type of location of each arguments without some information
394 // about the values that were passed in. This information could be retrieved
395 // from the printf format string, but the format string is not trivial to
396 // parse so we encode the relevant information with the HLT instruction.
397 // - Type
398 // Either kRegister or kFPRegister, but stored as a uint32_t because there's
399 // no way to guarantee the size of the CPURegister::RegisterType enum.
400 const unsigned kPrintfTypeOffset = 1 * kInstructionSize;
401 const unsigned kPrintfLength = 2 * kInstructionSize;
402
403 // A pseudo 'debug' instruction.
404 const Instr kImmExceptionIsDebug = 0xdeb0;
405 // Parameters are inlined in the code after a debug pseudo-instruction:
406 // - Debug code.
407 // - Debug parameters.
408 // - Debug message string. This is a NULL-terminated ASCII string, padded to
409 // kInstructionSize so that subsequent instructions are correctly aligned.
410 // - A kImmExceptionIsUnreachable marker, to catch accidental execution of the
411 // string data.
412 const unsigned kDebugCodeOffset = 1 * kInstructionSize;
413 const unsigned kDebugParamsOffset = 2 * kInstructionSize;
414 const unsigned kDebugMessageOffset = 3 * kInstructionSize;
415
416 // Debug parameters.
417 // Used without a TRACE_ option, the Debugger will print the arguments only
418 // once. Otherwise TRACE_ENABLE and TRACE_DISABLE will enable or disable tracing
419 // before every instruction for the specified LOG_ parameters.
420 //
421 // TRACE_OVERRIDE enables the specified LOG_ parameters, and disabled any
422 // others that were not specified.
423 //
424 // For example:
425 //
426 // __ debug("print registers and fp registers", 0, LOG_REGS | LOG_FP_REGS);
427 // will print the registers and fp registers only once.
428 //
429 // __ debug("trace disasm", 1, TRACE_ENABLE | LOG_DISASM);
430 // starts disassembling the code.
431 //
432 // __ debug("trace rets", 2, TRACE_ENABLE | LOG_REGS);
433 // adds the general purpose registers to the trace.
434 //
435 // __ debug("stop regs", 3, TRACE_DISABLE | LOG_REGS);
436 // stops tracing the registers.
437 const unsigned kDebuggerTracingDirectivesMask = 3 << 6;
438 enum DebugParameters {
439 NO_PARAM = 0,
440 BREAK = 1 << 0,
441 LOG_DISASM = 1 << 1, // Use only with TRACE. Disassemble the code.
442 LOG_REGS = 1 << 2, // Log general purpose registers.
443 LOG_FP_REGS = 1 << 3, // Log floating-point registers.
444 LOG_SYS_REGS = 1 << 4, // Log the status flags.
445 LOG_WRITE = 1 << 5, // Log any memory write.
446
447 LOG_STATE = LOG_REGS | LOG_FP_REGS | LOG_SYS_REGS,
448 LOG_ALL = LOG_DISASM | LOG_STATE | LOG_WRITE,
449
450 // Trace control.
451 TRACE_ENABLE = 1 << 6,
452 TRACE_DISABLE = 2 << 6,
453 TRACE_OVERRIDE = 3 << 6
454 };
455
456
457 } } // namespace v8::internal
458
459
460 #endif // V8_A64_INSTRUCTIONS_A64_H_
OLDNEW
« no previous file with comments | « src/a64/ic-a64.cc ('k') | src/a64/instructions-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698