Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 1 | // Copyright 2009 the V8 project authors. All rights reserved. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 4 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 5 | #if V8_TARGET_ARCH_ARM |
Leon Clarke | f7060e2 | 2010-06-03 12:02:55 +0100 | [diff] [blame] | 6 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 7 | #include "src/arm/constants-arm.h" |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 8 | |
| 9 | |
Steve Block | 1e0659c | 2011-05-24 12:43:12 +0100 | [diff] [blame] | 10 | namespace v8 { |
| 11 | namespace internal { |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 12 | |
Steve Block | 1e0659c | 2011-05-24 12:43:12 +0100 | [diff] [blame] | 13 | double Instruction::DoubleImmedVmov() const { |
Ben Murdoch | 3bec4d2 | 2010-07-22 14:51:16 +0100 | [diff] [blame] | 14 | // Reconstruct a double from the immediate encoded in the vmov instruction. |
| 15 | // |
| 16 | // instruction: [xxxxxxxx,xxxxabcd,xxxxxxxx,xxxxefgh] |
| 17 | // double: [aBbbbbbb,bbcdefgh,00000000,00000000, |
| 18 | // 00000000,00000000,00000000,00000000] |
| 19 | // |
| 20 | // where B = ~b. Only the high 16 bits are affected. |
| 21 | uint64_t high16; |
| 22 | high16 = (Bits(17, 16) << 4) | Bits(3, 0); // xxxxxxxx,xxcdefgh. |
| 23 | high16 |= (0xff * Bit(18)) << 6; // xxbbbbbb,bbxxxxxx. |
| 24 | high16 |= (Bit(18) ^ 1) << 14; // xBxxxxxx,xxxxxxxx. |
| 25 | high16 |= Bit(19) << 15; // axxxxxxx,xxxxxxxx. |
| 26 | |
| 27 | uint64_t imm = high16 << 48; |
| 28 | double d; |
| 29 | memcpy(&d, &imm, 8); |
| 30 | return d; |
| 31 | } |
| 32 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 33 | |
| 34 | // These register names are defined in a way to match the native disassembler |
| 35 | // formatting. See for example the command "objdump -d <binary file>". |
| 36 | const char* Registers::names_[kNumRegisters] = { |
| 37 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
| 38 | "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc", |
| 39 | }; |
| 40 | |
| 41 | |
| 42 | // List of alias names which can be used when referring to ARM registers. |
| 43 | const Registers::RegisterAlias Registers::aliases_[] = { |
| 44 | {10, "sl"}, |
| 45 | {11, "r11"}, |
| 46 | {12, "r12"}, |
| 47 | {13, "r13"}, |
| 48 | {14, "r14"}, |
| 49 | {15, "r15"}, |
| 50 | {kNoRegister, NULL} |
| 51 | }; |
| 52 | |
| 53 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 54 | // Support for VFP registers s0 to s31 (d0 to d15) and d16-d31. |
| 55 | // Note that "sN:sM" is the same as "dN/2" up to d15. |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 56 | // These register names are defined in a way to match the native disassembler |
| 57 | // formatting. See for example the command "objdump -d <binary file>". |
| 58 | const char* VFPRegisters::names_[kNumVFPRegisters] = { |
| 59 | "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", |
| 60 | "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", |
| 61 | "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", |
| 62 | "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", |
| 63 | "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 64 | "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", |
| 65 | "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", |
| 66 | "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31" |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 67 | }; |
| 68 | |
| 69 | |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 70 | const char* VFPRegisters::Name(int reg, bool is_double) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 71 | DCHECK((0 <= reg) && (reg < kNumVFPRegisters)); |
Steve Block | 8defd9f | 2010-07-08 12:39:36 +0100 | [diff] [blame] | 72 | return names_[reg + (is_double ? kNumVFPSingleRegisters : 0)]; |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 73 | } |
| 74 | |
| 75 | |
| 76 | int VFPRegisters::Number(const char* name, bool* is_double) { |
| 77 | for (int i = 0; i < kNumVFPRegisters; i++) { |
| 78 | if (strcmp(names_[i], name) == 0) { |
| 79 | if (i < kNumVFPSingleRegisters) { |
| 80 | *is_double = false; |
| 81 | return i; |
| 82 | } else { |
| 83 | *is_double = true; |
| 84 | return i - kNumVFPSingleRegisters; |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | // No register with the requested name found. |
| 90 | return kNoRegister; |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 91 | } |
| 92 | |
| 93 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 94 | int Registers::Number(const char* name) { |
| 95 | // Look through the canonical names. |
| 96 | for (int i = 0; i < kNumRegisters; i++) { |
| 97 | if (strcmp(names_[i], name) == 0) { |
| 98 | return i; |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | // Look through the alias names. |
| 103 | int i = 0; |
| 104 | while (aliases_[i].reg != kNoRegister) { |
| 105 | if (strcmp(aliases_[i].name, name) == 0) { |
| 106 | return aliases_[i].reg; |
| 107 | } |
| 108 | i++; |
| 109 | } |
| 110 | |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 111 | // No register with the requested name found. |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 112 | return kNoRegister; |
| 113 | } |
| 114 | |
| 115 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 116 | } // namespace internal |
| 117 | } // namespace v8 |
Leon Clarke | f7060e2 | 2010-06-03 12:02:55 +0100 | [diff] [blame] | 118 | |
| 119 | #endif // V8_TARGET_ARCH_ARM |