1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2009 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#if defined(V8_TARGET_ARCH_ARM)
31f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "constants-arm.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blocknamespace v8 {
361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blocknamespace internal {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockdouble Instruction::DoubleImmedVmov() const {
393bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // Reconstruct a double from the immediate encoded in the vmov instruction.
403bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  //
413bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  //   instruction: [xxxxxxxx,xxxxabcd,xxxxxxxx,xxxxefgh]
423bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  //   double: [aBbbbbbb,bbcdefgh,00000000,00000000,
433bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  //            00000000,00000000,00000000,00000000]
443bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  //
453bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // where B = ~b. Only the high 16 bits are affected.
463bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  uint64_t high16;
473bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  high16  = (Bits(17, 16) << 4) | Bits(3, 0);   // xxxxxxxx,xxcdefgh.
483bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  high16 |= (0xff * Bit(18)) << 6;              // xxbbbbbb,bbxxxxxx.
493bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  high16 |= (Bit(18) ^ 1) << 14;                // xBxxxxxx,xxxxxxxx.
503bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  high16 |= Bit(19) << 15;                      // axxxxxxx,xxxxxxxx.
513bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
523bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  uint64_t imm = high16 << 48;
533bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  double d;
543bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  memcpy(&d, &imm, 8);
553bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  return d;
563bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
573bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// These register names are defined in a way to match the native disassembler
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// formatting. See for example the command "objdump -d <binary file>".
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* Registers::names_[kNumRegisters] = {
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc",
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// List of alias names which can be used when referring to ARM registers.
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst Registers::RegisterAlias Registers::aliases_[] = {
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {10, "sl"},
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {11, "r11"},
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {12, "r12"},
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {13, "r13"},
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {14, "r14"},
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {15, "r15"},
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {kNoRegister, NULL}
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* Registers::Name(int reg) {
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* result;
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if ((0 <= reg) && (reg < kNumRegisters)) {
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = names_[reg];
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = "noreg";
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Support for VFP registers s0 to s31 (d0 to d15).
91d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Note that "sN:sM" is the same as "dN/2"
92d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// These register names are defined in a way to match the native disassembler
93d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// formatting. See for example the command "objdump -d <binary file>".
94d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockconst char* VFPRegisters::names_[kNumVFPRegisters] = {
95d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
96d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
97d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
98d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
99d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
100d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15"
101d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block};
102d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
103d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1046ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockconst char* VFPRegisters::Name(int reg, bool is_double) {
105d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ASSERT((0 <= reg) && (reg < kNumVFPRegisters));
1068defd9ff6930b4e24729971a61cf7469daf119beSteve Block  return names_[reg + (is_double ? kNumVFPSingleRegisters : 0)];
1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockint VFPRegisters::Number(const char* name, bool* is_double) {
1116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  for (int i = 0; i < kNumVFPRegisters; i++) {
1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (strcmp(names_[i], name) == 0) {
1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (i < kNumVFPSingleRegisters) {
1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        *is_double = false;
1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        return i;
1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      } else {
1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        *is_double = true;
1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        return i - kNumVFPSingleRegisters;
1196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
1216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // No register with the requested name found.
1246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return kNoRegister;
125d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
126d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
127d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Registers::Number(const char* name) {
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Look through the canonical names.
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kNumRegisters; i++) {
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (strcmp(names_[i], name) == 0) {
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return i;
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Look through the alias names.
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int i = 0;
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (aliases_[i].reg != kNoRegister) {
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (strcmp(aliases_[i].name, name) == 0) {
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return aliases_[i].reg;
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i++;
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // No register with the requested name found.
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return kNoRegister;
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} }  // namespace v8::internal
151f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
152f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif  // V8_TARGET_ARCH_ARM
153