| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 
|  | 2 // All Rights Reserved. | 
|  | 3 // | 
|  | 4 // Redistribution and use in source and binary forms, with or without | 
|  | 5 // modification, are permitted provided that the following conditions | 
|  | 6 // are met: | 
|  | 7 // | 
|  | 8 // - Redistributions of source code must retain the above copyright notice, | 
|  | 9 // this list of conditions and the following disclaimer. | 
|  | 10 // | 
|  | 11 // - Redistribution in binary form must reproduce the above copyright | 
|  | 12 // notice, this list of conditions and the following disclaimer in the | 
|  | 13 // documentation and/or other materials provided with the | 
|  | 14 // distribution. | 
|  | 15 // | 
|  | 16 // - Neither the name of Sun Microsystems or the names of contributors may | 
|  | 17 // be used to endorse or promote products derived from this software without | 
|  | 18 // specific prior written permission. | 
|  | 19 // | 
|  | 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 
|  | 23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | 
|  | 24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | 
|  | 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 
|  | 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
|  | 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
|  | 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 
|  | 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 
|  | 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 
|  | 31 // OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | 32 | 
|  | 33 // The original source code covered by the above license above has been | 
|  | 34 // modified significantly by Google Inc. | 
|  | 35 // Copyright 2014 the V8 project authors. All rights reserved. | 
|  | 36 | 
|  | 37 // A light-weight S390 Assembler | 
|  | 38 // Generates user mode instructions for z/Architecture | 
|  | 39 | 
|  | 40 #ifndef V8_S390_ASSEMBLER_S390_H_ | 
|  | 41 #define V8_S390_ASSEMBLER_S390_H_ | 
|  | 42 #include <stdio.h> | 
|  | 43 #if V8_HOST_ARCH_S390 | 
|  | 44 // elf.h include is required for auxv check for STFLE facility used | 
|  | 45 // for hardware detection, which is sensible only on s390 hosts. | 
|  | 46 #include <elf.h> | 
|  | 47 #endif | 
|  | 48 | 
|  | 49 #include <fcntl.h> | 
|  | 50 #include <unistd.h> | 
|  | 51 #include "src/assembler.h" | 
|  | 52 #include "src/s390/constants-s390.h" | 
|  | 53 | 
|  | 54 #define ABI_USES_FUNCTION_DESCRIPTORS 0 | 
|  | 55 | 
|  | 56 #define ABI_PASSES_HANDLES_IN_REGS 1 | 
|  | 57 | 
|  | 58 // ObjectPair is defined under runtime/runtime-util.h. | 
|  | 59 // On 31-bit, ObjectPair == uint64_t.  ABI dictates long long | 
|  | 60 //            be returned with the lower addressed half in r2 | 
|  | 61 //            and the higher addressed half in r3. (Returns in Regs) | 
|  | 62 // On 64-bit, ObjectPair is a Struct.  ABI dictaes Structs be | 
|  | 63 //            returned in a storage buffer allocated by the caller, | 
|  | 64 //            with the address of this buffer passed as a hidden | 
|  | 65 //            argument in r2. (Does NOT return in Regs) | 
|  | 66 // For x86 linux, ObjectPair is returned in registers. | 
|  | 67 #if V8_TARGET_ARCH_S390X | 
|  | 68 #define ABI_RETURNS_OBJECTPAIR_IN_REGS 0 | 
|  | 69 #else | 
|  | 70 #define ABI_RETURNS_OBJECTPAIR_IN_REGS 1 | 
|  | 71 #endif | 
|  | 72 | 
|  | 73 #define ABI_CALL_VIA_IP 1 | 
|  | 74 | 
|  | 75 #define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC | 
|  | 76 | 
|  | 77 namespace v8 { | 
|  | 78 namespace internal { | 
|  | 79 | 
|  | 80 // clang-format off | 
|  | 81 #define GENERAL_REGISTERS(V)                              \ | 
|  | 82   V(r0)  V(r1)  V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)  \ | 
|  | 83   V(r8)  V(r9)  V(r10) V(fp) V(ip) V(r13) V(r14) V(sp) | 
|  | 84 | 
|  | 85 #define ALLOCATABLE_GENERAL_REGISTERS(V)                  \ | 
|  | 86   V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)                \ | 
|  | 87   V(r8)  V(r9)  V(r13) | 
|  | 88 | 
|  | 89 #define DOUBLE_REGISTERS(V)                               \ | 
|  | 90   V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \ | 
|  | 91   V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) | 
|  | 92 | 
|  | 93 #define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \ | 
|  | 94   V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)         \ | 
|  | 95   V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d15) V(d0) | 
|  | 96 // clang-format on | 
|  | 97 | 
|  | 98 // CPU Registers. | 
|  | 99 // | 
|  | 100 // 1) We would prefer to use an enum, but enum values are assignment- | 
|  | 101 // compatible with int, which has caused code-generation bugs. | 
|  | 102 // | 
|  | 103 // 2) We would prefer to use a class instead of a struct but we don't like | 
|  | 104 // the register initialization to depend on the particular initialization | 
|  | 105 // order (which appears to be different on OS X, Linux, and Windows for the | 
|  | 106 // installed versions of C++ we tried). Using a struct permits C-style | 
|  | 107 // "initialization". Also, the Register objects cannot be const as this | 
|  | 108 // forces initialization stubs in MSVC, making us dependent on initialization | 
|  | 109 // order. | 
|  | 110 // | 
|  | 111 // 3) By not using an enum, we are possibly preventing the compiler from | 
|  | 112 // doing certain constant folds, which may significantly reduce the | 
|  | 113 // code generated for some assembly instructions (because they boil down | 
|  | 114 // to a few constants). If this is a problem, we could change the code | 
|  | 115 // such that we use an enum in optimized mode, and the struct in debug | 
|  | 116 // mode. This way we get the compile-time error checking in debug mode | 
|  | 117 // and best performance in optimized code. | 
|  | 118 | 
|  | 119 struct Register { | 
|  | 120   enum Code { | 
|  | 121 #define REGISTER_CODE(R) kCode_##R, | 
|  | 122     GENERAL_REGISTERS(REGISTER_CODE) | 
|  | 123 #undef REGISTER_CODE | 
|  | 124         kAfterLast, | 
|  | 125     kCode_no_reg = -1 | 
|  | 126   }; | 
|  | 127   static const int kNumRegisters = Code::kAfterLast; | 
|  | 128 | 
|  | 129 #define REGISTER_COUNT(R) 1 + | 
|  | 130   static const int kNumAllocatable = | 
|  | 131       ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT) 0; | 
|  | 132 #undef REGISTER_COUNT | 
|  | 133 | 
|  | 134 #define REGISTER_BIT(R) 1 << kCode_##R | | 
|  | 135   static const RegList kAllocatable = | 
|  | 136       ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT) 0; | 
|  | 137 #undef REGISTER_BIT | 
|  | 138 | 
|  | 139   static Register from_code(int code) { | 
|  | 140     DCHECK(code >= 0); | 
|  | 141     DCHECK(code < kNumRegisters); | 
|  | 142     Register r = {code}; | 
|  | 143     return r; | 
|  | 144   } | 
|  | 145 | 
|  | 146   const char* ToString(); | 
|  | 147   bool IsAllocatable() const; | 
|  | 148   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } | 
|  | 149   bool is(Register reg) const { return reg_code == reg.reg_code; } | 
|  | 150   int code() const { | 
|  | 151     DCHECK(is_valid()); | 
|  | 152     return reg_code; | 
|  | 153   } | 
|  | 154   int bit() const { | 
|  | 155     DCHECK(is_valid()); | 
|  | 156     return 1 << reg_code; | 
|  | 157   } | 
|  | 158 | 
|  | 159   void set_code(int code) { | 
|  | 160     reg_code = code; | 
|  | 161     DCHECK(is_valid()); | 
|  | 162   } | 
|  | 163 | 
|  | 164 #if V8_TARGET_LITTLE_ENDIAN | 
|  | 165   static const int kMantissaOffset = 0; | 
|  | 166   static const int kExponentOffset = 4; | 
|  | 167 #else | 
|  | 168   static const int kMantissaOffset = 4; | 
|  | 169   static const int kExponentOffset = 0; | 
|  | 170 #endif | 
|  | 171 | 
|  | 172   // Unfortunately we can't make this private in a struct. | 
|  | 173   int reg_code; | 
|  | 174 }; | 
|  | 175 | 
|  | 176 typedef struct Register Register; | 
|  | 177 | 
|  | 178 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; | 
|  | 179 GENERAL_REGISTERS(DECLARE_REGISTER) | 
|  | 180 #undef DECLARE_REGISTER | 
|  | 181 const Register no_reg = {Register::kCode_no_reg}; | 
|  | 182 | 
|  | 183 // Register aliases | 
|  | 184 const Register kLithiumScratch = r1;  // lithium scratch. | 
|  | 185 const Register kRootRegister = r10;   // Roots array pointer. | 
|  | 186 const Register cp = r13;              // JavaScript context pointer. | 
|  | 187 | 
|  | 188 // Double word FP register. | 
|  | 189 struct DoubleRegister { | 
|  | 190   enum Code { | 
|  | 191 #define REGISTER_CODE(R) kCode_##R, | 
|  | 192     DOUBLE_REGISTERS(REGISTER_CODE) | 
|  | 193 #undef REGISTER_CODE | 
|  | 194         kAfterLast, | 
|  | 195     kCode_no_reg = -1 | 
|  | 196   }; | 
|  | 197 | 
|  | 198   static const int kNumRegisters = Code::kAfterLast; | 
|  | 199   static const int kMaxNumRegisters = kNumRegisters; | 
|  | 200 | 
|  | 201   const char* ToString(); | 
|  | 202   bool IsAllocatable() const; | 
|  | 203   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } | 
|  | 204   bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } | 
|  | 205 | 
|  | 206   int code() const { | 
|  | 207     DCHECK(is_valid()); | 
|  | 208     return reg_code; | 
|  | 209   } | 
|  | 210 | 
|  | 211   int bit() const { | 
|  | 212     DCHECK(is_valid()); | 
|  | 213     return 1 << reg_code; | 
|  | 214   } | 
|  | 215 | 
|  | 216   static DoubleRegister from_code(int code) { | 
|  | 217     DoubleRegister r = {code}; | 
|  | 218     return r; | 
|  | 219   } | 
|  | 220 | 
|  | 221   int reg_code; | 
|  | 222 }; | 
|  | 223 | 
|  | 224 typedef DoubleRegister DoubleRegister; | 
|  | 225 | 
|  | 226 #define DECLARE_REGISTER(R) \ | 
|  | 227   const DoubleRegister R = {DoubleRegister::kCode_##R}; | 
|  | 228 DOUBLE_REGISTERS(DECLARE_REGISTER) | 
|  | 229 #undef DECLARE_REGISTER | 
|  | 230 const Register no_dreg = {Register::kCode_no_reg}; | 
|  | 231 | 
|  | 232 // Aliases for double registers.  Defined using #define instead of | 
|  | 233 // "static const DoubleRegister&" because Clang complains otherwise when a | 
|  | 234 // compilation unit that includes this header doesn't use the variables. | 
|  | 235 #define kDoubleRegZero d14 | 
|  | 236 #define kScratchDoubleReg d13 | 
|  | 237 | 
|  | 238 Register ToRegister(int num); | 
|  | 239 | 
|  | 240 // Coprocessor register | 
|  | 241 struct CRegister { | 
|  | 242   bool is_valid() const { return 0 <= reg_code && reg_code < 16; } | 
|  | 243   bool is(CRegister creg) const { return reg_code == creg.reg_code; } | 
|  | 244   int code() const { | 
|  | 245     DCHECK(is_valid()); | 
|  | 246     return reg_code; | 
|  | 247   } | 
|  | 248   int bit() const { | 
|  | 249     DCHECK(is_valid()); | 
|  | 250     return 1 << reg_code; | 
|  | 251   } | 
|  | 252 | 
|  | 253   // Unfortunately we can't make this private in a struct. | 
|  | 254   int reg_code; | 
|  | 255 }; | 
|  | 256 | 
|  | 257 const CRegister no_creg = {-1}; | 
|  | 258 | 
|  | 259 const CRegister cr0 = {0}; | 
|  | 260 const CRegister cr1 = {1}; | 
|  | 261 const CRegister cr2 = {2}; | 
|  | 262 const CRegister cr3 = {3}; | 
|  | 263 const CRegister cr4 = {4}; | 
|  | 264 const CRegister cr5 = {5}; | 
|  | 265 const CRegister cr6 = {6}; | 
|  | 266 const CRegister cr7 = {7}; | 
|  | 267 const CRegister cr8 = {8}; | 
|  | 268 const CRegister cr9 = {9}; | 
|  | 269 const CRegister cr10 = {10}; | 
|  | 270 const CRegister cr11 = {11}; | 
|  | 271 const CRegister cr12 = {12}; | 
|  | 272 const CRegister cr13 = {13}; | 
|  | 273 const CRegister cr14 = {14}; | 
|  | 274 const CRegister cr15 = {15}; | 
|  | 275 | 
|  | 276 // TODO(john.yan) Define SIMD registers. | 
|  | 277 typedef DoubleRegister Simd128Register; | 
|  | 278 | 
|  | 279 // ----------------------------------------------------------------------------- | 
|  | 280 // Machine instruction Operands | 
|  | 281 | 
|  | 282 #if V8_TARGET_ARCH_S390X | 
|  | 283 const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64; | 
|  | 284 #else | 
|  | 285 const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE32; | 
|  | 286 #endif | 
|  | 287 | 
|  | 288 // Class Operand represents a shifter operand in data processing instructions | 
|  | 289 // defining immediate numbers and masks | 
|  | 290 typedef uint8_t Length; | 
|  | 291 | 
|  | 292 struct Mask { | 
|  | 293   uint8_t mask; | 
|  | 294   uint8_t value() { return mask; } | 
|  | 295   static Mask from_value(uint8_t input) { | 
|  | 296     DCHECK(input <= 0x0F); | 
|  | 297     Mask m = {input}; | 
|  | 298     return m; | 
|  | 299   } | 
|  | 300 }; | 
|  | 301 | 
|  | 302 class Operand BASE_EMBEDDED { | 
|  | 303  public: | 
|  | 304   // immediate | 
|  | 305   INLINE(explicit Operand(intptr_t immediate, | 
|  | 306                           RelocInfo::Mode rmode = kRelocInfo_NONEPTR)); | 
|  | 307   INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); } | 
|  | 308   INLINE(explicit Operand(const ExternalReference& f)); | 
|  | 309   explicit Operand(Handle<Object> handle); | 
|  | 310   INLINE(explicit Operand(Smi* value)); | 
|  | 311 | 
|  | 312   // rm | 
|  | 313   INLINE(explicit Operand(Register rm)); | 
|  | 314 | 
|  | 315   // Return true if this is a register operand. | 
|  | 316   INLINE(bool is_reg() const); | 
|  | 317 | 
|  | 318   bool must_output_reloc_info(const Assembler* assembler) const; | 
|  | 319 | 
|  | 320   inline intptr_t immediate() const { | 
|  | 321     DCHECK(!rm_.is_valid()); | 
|  | 322     return imm_; | 
|  | 323   } | 
|  | 324 | 
|  | 325   inline void setBits(int n) { | 
|  | 326     imm_ = (static_cast<uint32_t>(imm_) << (32 - n)) >> (32 - n); | 
|  | 327   } | 
|  | 328 | 
|  | 329   Register rm() const { return rm_; } | 
|  | 330 | 
|  | 331  private: | 
|  | 332   Register rm_; | 
|  | 333   intptr_t imm_;  // valid if rm_ == no_reg | 
|  | 334   RelocInfo::Mode rmode_; | 
|  | 335 | 
|  | 336   friend class Assembler; | 
|  | 337   friend class MacroAssembler; | 
|  | 338 }; | 
|  | 339 | 
|  | 340 typedef int32_t Disp; | 
|  | 341 | 
|  | 342 // Class MemOperand represents a memory operand in load and store instructions | 
|  | 343 // On S390, we have various flavours of memory operands: | 
|  | 344 //   1) a base register + 16 bit unsigned displacement | 
|  | 345 //   2) a base register + index register + 16 bit unsigned displacement | 
|  | 346 //   3) a base register + index register + 20 bit signed displacement | 
|  | 347 class MemOperand BASE_EMBEDDED { | 
|  | 348  public: | 
|  | 349   explicit MemOperand(Register rx, Disp offset = 0); | 
|  | 350   explicit MemOperand(Register rx, Register rb, Disp offset = 0); | 
|  | 351 | 
|  | 352   int32_t offset() const { return offset_; } | 
|  | 353   uint32_t getDisplacement() const { return offset(); } | 
|  | 354 | 
|  | 355   // Base register | 
|  | 356   Register rb() const { | 
|  | 357     DCHECK(!baseRegister.is(no_reg)); | 
|  | 358     return baseRegister; | 
|  | 359   } | 
|  | 360 | 
|  | 361   Register getBaseRegister() const { return rb(); } | 
|  | 362 | 
|  | 363   // Index Register | 
|  | 364   Register rx() const { | 
|  | 365     DCHECK(!indexRegister.is(no_reg)); | 
|  | 366     return indexRegister; | 
|  | 367   } | 
|  | 368   Register getIndexRegister() const { return rx(); } | 
|  | 369 | 
|  | 370  private: | 
|  | 371   Register baseRegister;   // base | 
|  | 372   Register indexRegister;  // index | 
|  | 373   int32_t offset_;         // offset | 
|  | 374 | 
|  | 375   friend class Assembler; | 
|  | 376 }; | 
|  | 377 | 
|  | 378 class DeferredRelocInfo { | 
|  | 379  public: | 
|  | 380   DeferredRelocInfo() {} | 
|  | 381   DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data) | 
|  | 382       : position_(position), rmode_(rmode), data_(data) {} | 
|  | 383 | 
|  | 384   int position() const { return position_; } | 
|  | 385   RelocInfo::Mode rmode() const { return rmode_; } | 
|  | 386   intptr_t data() const { return data_; } | 
|  | 387 | 
|  | 388  private: | 
|  | 389   int position_; | 
|  | 390   RelocInfo::Mode rmode_; | 
|  | 391   intptr_t data_; | 
|  | 392 }; | 
|  | 393 | 
|  | 394 class Assembler : public AssemblerBase { | 
|  | 395  public: | 
|  | 396   // Create an assembler. Instructions and relocation information are emitted | 
|  | 397   // into a buffer, with the instructions starting from the beginning and the | 
|  | 398   // relocation information starting from the end of the buffer. See CodeDesc | 
|  | 399   // for a detailed comment on the layout (globals.h). | 
|  | 400   // | 
|  | 401   // If the provided buffer is NULL, the assembler allocates and grows its own | 
|  | 402   // buffer, and buffer_size determines the initial buffer size. The buffer is | 
|  | 403   // owned by the assembler and deallocated upon destruction of the assembler. | 
|  | 404   // | 
|  | 405   // If the provided buffer is not NULL, the assembler uses the provided buffer | 
|  | 406   // for code generation and assumes its size to be buffer_size. If the buffer | 
|  | 407   // is too small, a fatal error occurs. No deallocation of the buffer is done | 
|  | 408   // upon destruction of the assembler. | 
|  | 409   Assembler(Isolate* isolate, void* buffer, int buffer_size); | 
|  | 410   virtual ~Assembler() {} | 
|  | 411 | 
|  | 412   // GetCode emits any pending (non-emitted) code and fills the descriptor | 
|  | 413   // desc. GetCode() is idempotent; it returns the same result if no other | 
|  | 414   // Assembler functions are invoked in between GetCode() calls. | 
|  | 415   void GetCode(CodeDesc* desc); | 
|  | 416 | 
|  | 417   // Label operations & relative jumps (PPUM Appendix D) | 
|  | 418   // | 
|  | 419   // Takes a branch opcode (cc) and a label (L) and generates | 
|  | 420   // either a backward branch or a forward branch and links it | 
|  | 421   // to the label fixup chain. Usage: | 
|  | 422   // | 
|  | 423   // Label L;    // unbound label | 
|  | 424   // j(cc, &L);  // forward branch to unbound label | 
|  | 425   // bind(&L);   // bind label to the current pc | 
|  | 426   // j(cc, &L);  // backward branch to bound label | 
|  | 427   // bind(&L);   // illegal: a label may be bound only once | 
|  | 428   // | 
|  | 429   // Note: The same Label can be used for forward and backward branches | 
|  | 430   // but it may be bound only once. | 
|  | 431 | 
|  | 432   void bind(Label* L);  // binds an unbound label L to the current code position | 
|  | 433 | 
|  | 434   // Links a label at the current pc_offset().  If already bound, returns the | 
|  | 435   // bound position.  If already linked, returns the position of the prior link. | 
|  | 436   // Otherwise, returns the current pc_offset(). | 
|  | 437   int link(Label* L); | 
|  | 438 | 
|  | 439   // Determines if Label is bound and near enough so that a single | 
|  | 440   // branch instruction can be used to reach it. | 
|  | 441   bool is_near(Label* L, Condition cond); | 
|  | 442 | 
|  | 443   // Returns the branch offset to the given label from the current code position | 
|  | 444   // Links the label to the current position if it is still unbound | 
|  | 445   int branch_offset(Label* L) { return link(L) - pc_offset(); } | 
|  | 446 | 
|  | 447   // Puts a labels target address at the given position. | 
|  | 448   // The high 8 bits are set to zero. | 
|  | 449   void label_at_put(Label* L, int at_offset); | 
|  | 450   void load_label_offset(Register r1, Label* L); | 
|  | 451 | 
|  | 452   // Read/Modify the code target address in the branch/call instruction at pc. | 
|  | 453   INLINE(static Address target_address_at(Address pc, Address constant_pool)); | 
|  | 454   INLINE(static void set_target_address_at( | 
|  | 455       Isolate* isolate, Address pc, Address constant_pool, Address target, | 
|  | 456       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); | 
|  | 457   INLINE(static Address target_address_at(Address pc, Code* code)) { | 
|  | 458     Address constant_pool = NULL; | 
|  | 459     return target_address_at(pc, constant_pool); | 
|  | 460   } | 
|  | 461   INLINE(static void set_target_address_at( | 
|  | 462       Isolate* isolate, Address pc, Code* code, Address target, | 
|  | 463       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) { | 
|  | 464     Address constant_pool = NULL; | 
|  | 465     set_target_address_at(isolate, pc, constant_pool, target, | 
|  | 466                           icache_flush_mode); | 
|  | 467   } | 
|  | 468 | 
|  | 469   // Return the code target address at a call site from the return address | 
|  | 470   // of that call in the instruction stream. | 
|  | 471   inline static Address target_address_from_return_address(Address pc); | 
|  | 472 | 
|  | 473   // Given the address of the beginning of a call, return the address | 
|  | 474   // in the instruction stream that the call will return to. | 
|  | 475   INLINE(static Address return_address_from_call_start(Address pc)); | 
|  | 476 | 
|  | 477   inline Handle<Object> code_target_object_handle_at(Address pc); | 
|  | 478   // This sets the branch destination. | 
|  | 479   // This is for calls and branches within generated code. | 
|  | 480   inline static void deserialization_set_special_target_at( | 
|  | 481       Isolate* isolate, Address instruction_payload, Code* code, | 
|  | 482       Address target); | 
|  | 483 | 
|  | 484   // This sets the internal reference at the pc. | 
|  | 485   inline static void deserialization_set_target_internal_reference_at( | 
|  | 486       Isolate* isolate, Address pc, Address target, | 
|  | 487       RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); | 
|  | 488 | 
|  | 489   // Here we are patching the address in the IIHF/IILF instruction pair. | 
|  | 490   // These values are used in the serialization process and must be zero for | 
|  | 491   // S390 platform, as Code, Embedded Object or External-reference pointers | 
|  | 492   // are split across two consecutive instructions and don't exist separately | 
|  | 493   // in the code, so the serializer should not step forwards in memory after | 
|  | 494   // a target is resolved and written. | 
|  | 495   static const int kSpecialTargetSize = 0; | 
|  | 496 | 
|  | 497 // Number of bytes for instructions used to store pointer sized constant. | 
|  | 498 #if V8_TARGET_ARCH_S390X | 
|  | 499   static const int kBytesForPtrConstant = 12;  // IIHF + IILF | 
|  | 500 #else | 
|  | 501   static const int kBytesForPtrConstant = 6;  // IILF | 
|  | 502 #endif | 
|  | 503 | 
|  | 504   // Distance between the instruction referring to the address of the call | 
|  | 505   // target and the return address. | 
|  | 506 | 
|  | 507   // Offset between call target address and return address | 
|  | 508   // for BRASL calls | 
|  | 509   // Patch will be appiled to other FIXED_SEQUENCE call | 
|  | 510   static const int kCallTargetAddressOffset = 6; | 
|  | 511 | 
|  | 512 // The length of FIXED_SEQUENCE call | 
|  | 513 // iihf    r8, <address_hi>  // <64-bit only> | 
|  | 514 // iilf    r8, <address_lo> | 
|  | 515 // basr    r14, r8 | 
|  | 516 #if V8_TARGET_ARCH_S390X | 
|  | 517   static const int kCallSequenceLength = 14; | 
|  | 518 #else | 
|  | 519   static const int kCallSequenceLength = 8; | 
|  | 520 #endif | 
|  | 521 | 
|  | 522   // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn() | 
|  | 523   // code patch FIXED_SEQUENCE in bytes! | 
|  | 524   // JS Return Sequence = Call Sequence + BKPT | 
|  | 525   // static const int kJSReturnSequenceLength = kCallSequenceLength + 2; | 
|  | 526 | 
|  | 527   // This is the length of the code sequence from SetDebugBreakAtSlot() | 
|  | 528   // FIXED_SEQUENCE in bytes! | 
|  | 529   static const int kDebugBreakSlotLength = kCallSequenceLength; | 
|  | 530   static const int kPatchDebugBreakSlotReturnOffset = kCallTargetAddressOffset; | 
|  | 531 | 
|  | 532   // Length to patch between the start of the JS return sequence | 
|  | 533   // from SetDebugBreakAtReturn and the address from | 
|  | 534   // break_address_from_return_address. | 
|  | 535   // | 
|  | 536   // frame->pc() in Debug::SetAfterBreakTarget will point to BKPT in | 
|  | 537   // JS return sequence, so the length to patch will not include BKPT | 
|  | 538   // instruction length. | 
|  | 539   // static const int kPatchReturnSequenceAddressOffset = | 
|  | 540   //     kCallSequenceLength - kPatchDebugBreakSlotReturnOffset; | 
|  | 541 | 
|  | 542   // Length to patch between the start of the FIXED call sequence from | 
|  | 543   // SetDebugBreakAtSlot() and the the address from | 
|  | 544   // break_address_from_return_address. | 
|  | 545   static const int kPatchDebugBreakSlotAddressOffset = | 
|  | 546       kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset; | 
|  | 547 | 
|  | 548   static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { | 
|  | 549     return ((cr.code() * CRWIDTH) + crbit); | 
|  | 550   } | 
|  | 551 | 
|  | 552   // --------------------------------------------------------------------------- | 
|  | 553   // Code generation | 
|  | 554 | 
|  | 555   // Helper for unconditional branch to Label with update to save register | 
|  | 556   void b(Register r, Label* l) { | 
|  | 557     positions_recorder()->WriteRecordedPositions(); | 
|  | 558     int32_t halfwords = branch_offset(l) / 2; | 
|  | 559     brasl(r, Operand(halfwords)); | 
|  | 560   } | 
|  | 561 | 
|  | 562   // Conditional Branch Instruction - Generates either BRC / BRCL | 
|  | 563   void branchOnCond(Condition c, int branch_offset, bool is_bound = false); | 
|  | 564 | 
|  | 565   // Helpers for conditional branch to Label | 
|  | 566   void b(Condition cond, Label* l, Label::Distance dist = Label::kFar) { | 
|  | 567     branchOnCond(cond, branch_offset(l), | 
|  | 568                  l->is_bound() || (dist == Label::kNear)); | 
|  | 569   } | 
|  | 570 | 
|  | 571   void bc_short(Condition cond, Label* l, Label::Distance dist = Label::kFar) { | 
|  | 572     b(cond, l, Label::kNear); | 
|  | 573   } | 
|  | 574   // Helpers for conditional branch to Label | 
|  | 575   void beq(Label* l, Label::Distance dist = Label::kFar) { b(eq, l, dist); } | 
|  | 576   void bne(Label* l, Label::Distance dist = Label::kFar) { b(ne, l, dist); } | 
|  | 577   void blt(Label* l, Label::Distance dist = Label::kFar) { b(lt, l, dist); } | 
|  | 578   void ble(Label* l, Label::Distance dist = Label::kFar) { b(le, l, dist); } | 
|  | 579   void bgt(Label* l, Label::Distance dist = Label::kFar) { b(gt, l, dist); } | 
|  | 580   void bge(Label* l, Label::Distance dist = Label::kFar) { b(ge, l, dist); } | 
|  | 581   void b(Label* l, Label::Distance dist = Label::kFar) { b(al, l, dist); } | 
|  | 582   void jmp(Label* l, Label::Distance dist = Label::kFar) { b(al, l, dist); } | 
|  | 583   void bunordered(Label* l, Label::Distance dist = Label::kFar) { | 
|  | 584     b(unordered, l, dist); | 
|  | 585   } | 
|  | 586   void bordered(Label* l, Label::Distance dist = Label::kFar) { | 
|  | 587     b(ordered, l, dist); | 
|  | 588   } | 
|  | 589 | 
|  | 590   // Helpers for conditional indirect branch off register | 
|  | 591   void b(Condition cond, Register r) { bcr(cond, r); } | 
|  | 592   void beq(Register r) { b(eq, r); } | 
|  | 593   void bne(Register r) { b(ne, r); } | 
|  | 594   void blt(Register r) { b(lt, r); } | 
|  | 595   void ble(Register r) { b(le, r); } | 
|  | 596   void bgt(Register r) { b(gt, r); } | 
|  | 597   void bge(Register r) { b(ge, r); } | 
|  | 598   void b(Register r) { b(al, r); } | 
|  | 599   void jmp(Register r) { b(al, r); } | 
|  | 600   void bunordered(Register r) { b(unordered, r); } | 
|  | 601   void bordered(Register r) { b(ordered, r); } | 
|  | 602 | 
|  | 603   // --------------------------------------------------------------------------- | 
|  | 604   // Code generation | 
|  | 605 | 
|  | 606   // Insert the smallest number of nop instructions | 
|  | 607   // possible to align the pc offset to a multiple | 
|  | 608   // of m. m must be a power of 2 (>= 4). | 
|  | 609   void Align(int m); | 
|  | 610   // Insert the smallest number of zero bytes possible to align the pc offset | 
|  | 611   // to a mulitple of m. m must be a power of 2 (>= 2). | 
|  | 612   void DataAlign(int m); | 
|  | 613   // Aligns code to something that's optimal for a jump target for the platform. | 
|  | 614   void CodeTargetAlign(); | 
|  | 615 | 
|  | 616   void breakpoint(bool do_print) { | 
|  | 617     if (do_print) { | 
|  | 618       printf("DebugBreak is inserted to %p\n", pc_); | 
|  | 619     } | 
|  | 620 #if V8_HOST_ARCH_64_BIT | 
|  | 621     int64_t value = reinterpret_cast<uint64_t>(&v8::base::OS::DebugBreak); | 
|  | 622     int32_t hi_32 = static_cast<int64_t>(value) >> 32; | 
|  | 623     int32_t lo_32 = static_cast<int32_t>(value); | 
|  | 624 | 
|  | 625     iihf(r1, Operand(hi_32)); | 
|  | 626     iilf(r1, Operand(lo_32)); | 
|  | 627 #else | 
|  | 628     iilf(r1, Operand(reinterpret_cast<uint32_t>(&v8::base::OS::DebugBreak))); | 
|  | 629 #endif | 
|  | 630     basr(r14, r1); | 
|  | 631   } | 
|  | 632 | 
|  | 633   void call(Handle<Code> target, RelocInfo::Mode rmode, | 
|  | 634             TypeFeedbackId ast_id = TypeFeedbackId::None()); | 
|  | 635   void jump(Handle<Code> target, RelocInfo::Mode rmode, Condition cond); | 
|  | 636 | 
|  | 637 // S390 instruction generation | 
|  | 638 #define I_FORM(name) void name(const Operand& i) | 
|  | 639 | 
|  | 640 #define RR_FORM(name) void name(Register r1, Register r2) | 
|  | 641 | 
|  | 642 #define RR2_FORM(name) void name(Condition m1, Register r2) | 
|  | 643 | 
|  | 644 #define RX_FORM(name)                                        \ | 
|  | 645   void name(Register r1, Register x2, Register b2, Disp d2); \ | 
|  | 646   void name(Register r1, const MemOperand& opnd) | 
|  | 647 | 
|  | 648 #define RI1_FORM(name) void name(Register r, const Operand& i) | 
|  | 649 | 
|  | 650 #define RI2_FORM(name) void name(Condition m, const Operand& i) | 
|  | 651 | 
|  | 652 #define RIE_FORM(name) void name(Register r1, Register R3, const Operand& i) | 
|  | 653 | 
|  | 654 #define RIE_F_FORM(name)                                                    \ | 
|  | 655   void name(Register r1, Register r2, const Operand& i3, const Operand& i4, \ | 
|  | 656             const Operand& i5) | 
|  | 657 | 
|  | 658 #define RIL1_FORM(name) void name(Register r1, const Operand& i2) | 
|  | 659 | 
|  | 660 #define RIL2_FORM(name) void name(Condition m1, const Operand& i2) | 
|  | 661 | 
|  | 662 #define RXE_FORM(name)                            \ | 
|  | 663   void name(Register r1, const MemOperand& opnd); \ | 
|  | 664   void name(Register r1, Register b2, Register x2, Disp d2) | 
|  | 665 | 
|  | 666 #define RXF_FORM(name)                                         \ | 
|  | 667   void name(Register r1, Register r3, const MemOperand& opnd); \ | 
|  | 668   void name(Register r1, Register r3, Register b2, Register x2, Disp d2) | 
|  | 669 | 
|  | 670 #define RXY_FORM(name)                                       \ | 
|  | 671   void name(Register r1, Register x2, Register b2, Disp d2); \ | 
|  | 672   void name(Register r1, const MemOperand& opnd) | 
|  | 673 | 
|  | 674 #define RSI_FORM(name) void name(Register r1, Register r3, const Operand& i) | 
|  | 675 | 
|  | 676 #define RIS_FORM(name)                                       \ | 
|  | 677   void name(Register r1, Condition m3, Register b4, Disp d4, \ | 
|  | 678             const Operand& i2);                              \ | 
|  | 679   void name(Register r1, const Operand& i2, Condition m3,    \ | 
|  | 680             const MemOperand& opnd) | 
|  | 681 | 
|  | 682 #define SI_FORM(name)                                  \ | 
|  | 683   void name(const MemOperand& opnd, const Operand& i); \ | 
|  | 684   void name(const Operand& i2, Register b1, Disp d1) | 
|  | 685 | 
|  | 686 #define SIL_FORM(name)                                \ | 
|  | 687   void name(Register b1, Disp d1, const Operand& i2); \ | 
|  | 688   void name(const MemOperand& opnd, const Operand& i2) | 
|  | 689 | 
|  | 690 #define RRE_FORM(name) void name(Register r1, Register r2) | 
|  | 691 | 
|  | 692 #define RRF1_FORM(name) void name(Register r1, Register r2, Register r3) | 
|  | 693 | 
|  | 694 #define RRF2_FORM(name) void name(Condition m1, Register r1, Register r2) | 
|  | 695 | 
|  | 696 #define RRF3_FORM(name) \ | 
|  | 697   void name(Register r3, Condition m4, Register r1, Register r2) | 
|  | 698 | 
|  | 699 #define RS1_FORM(name)                                         \ | 
|  | 700   void name(Register r1, Register r3, const MemOperand& opnd); \ | 
|  | 701   void name(Register r1, Register r3, Register b2, Disp d2) | 
|  | 702 | 
|  | 703 #define RS2_FORM(name)                                          \ | 
|  | 704   void name(Register r1, Condition m3, const MemOperand& opnd); \ | 
|  | 705   void name(Register r1, Condition m3, Register b2, Disp d2) | 
|  | 706 | 
|  | 707 #define RSE_FORM(name)                                         \ | 
|  | 708   void name(Register r1, Register r3, const MemOperand& opnd); \ | 
|  | 709   void name(Register r1, Register r3, Register b2, Disp d2) | 
|  | 710 | 
|  | 711 #define RSL_FORM(name)                       \ | 
|  | 712   void name(Length l, Register b2, Disp d2); \ | 
|  | 713   void name(const MemOperand& opnd) | 
|  | 714 | 
|  | 715 #define RSY1_FORM(name)                                      \ | 
|  | 716   void name(Register r1, Register r3, Register b2, Disp d2); \ | 
|  | 717   void name(Register r1, Register r3, const MemOperand& opnd) | 
|  | 718 | 
|  | 719 #define RSY2_FORM(name)                                       \ | 
|  | 720   void name(Register r1, Condition m3, Register b2, Disp d2); \ | 
|  | 721   void name(Register r1, Condition m3, const MemOperand& opnd) | 
|  | 722 | 
|  | 723 #define RRD_FORM(name) void name(Register r1, Register r3, Register r2) | 
|  | 724 | 
|  | 725 #define RRS_FORM(name)                                                     \ | 
|  | 726   void name(Register r1, Register r2, Register b4, Disp d4, Condition m3); \ | 
|  | 727   void name(Register r1, Register r2, Condition m3, const MemOperand& opnd) | 
|  | 728 | 
|  | 729 #define S_FORM(name)               \ | 
|  | 730   void name(Register b2, Disp d2); \ | 
|  | 731   void name(const MemOperand& opnd) | 
|  | 732 | 
|  | 733 #define SIY_FORM(name)                                \ | 
|  | 734   void name(const Operand& i2, Register b1, Disp d1); \ | 
|  | 735   void name(const MemOperand& opnd, const Operand& i) | 
|  | 736 | 
|  | 737 #define SS1_FORM(name)                                                  \ | 
|  | 738   void name(Register b1, Disp d1, Register b3, Disp d2, Length length); \ | 
|  | 739   void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length) | 
|  | 740 | 
|  | 741 #define SS2_FORM(name)                                                        \ | 
|  | 742   void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length1, \ | 
|  | 743             Length length2);                                                  \ | 
|  | 744   void name(Register b1, Disp d1, Register b2, Disp d2, Length l1, Length l2) | 
|  | 745 | 
|  | 746 #define SS3_FORM(name)                                                        \ | 
|  | 747   void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length); \ | 
|  | 748   void name(const Operand& i3, Register b1, Disp d1, Register b2, Disp d2,    \ | 
|  | 749             Length l1) | 
|  | 750 | 
|  | 751 #define SS4_FORM(name)                                                   \ | 
|  | 752   void name(const MemOperand& opnd1, const MemOperand& opnd2);           \ | 
|  | 753   void name(Register r1, Register r3, Register b1, Disp d1, Register b2, \ | 
|  | 754             Disp d2) | 
|  | 755 | 
|  | 756 #define SS5_FORM(name)                                                   \ | 
|  | 757   void name(const MemOperand& opnd1, const MemOperand& opnd2);           \ | 
|  | 758   void name(Register r1, Register r3, Register b3, Disp d2, Register b4, \ | 
|  | 759             Disp d4) | 
|  | 760 | 
|  | 761 #define SSE_FORM(name)                                   \ | 
|  | 762   void name(Register b1, Disp d1, Register b2, Disp d2); \ | 
|  | 763   void name(const MemOperand& opnd1, const MemOperand& opnd2) | 
|  | 764 | 
|  | 765 #define SSF_FORM(name)                                                \ | 
|  | 766   void name(Register r3, Register b1, Disp d1, Register b2, Disp d2); \ | 
|  | 767   void name(Register r3, const MemOperand& opnd1, const MemOperand& opnd2) | 
|  | 768 | 
|  | 769   // S390 instruction sets | 
|  | 770   RX_FORM(bc); | 
|  | 771   RR_FORM(bctr); | 
|  | 772   RX_FORM(cd); | 
|  | 773   RRE_FORM(cdr); | 
|  | 774   RXE_FORM(cdb); | 
|  | 775   RXE_FORM(ceb); | 
|  | 776   RRE_FORM(cefbr); | 
|  | 777   RXE_FORM(ddb); | 
|  | 778   RRE_FORM(ddbr); | 
|  | 779   SS1_FORM(ed); | 
|  | 780   RRE_FORM(epair); | 
|  | 781   RX_FORM(ex); | 
|  | 782   RRF2_FORM(fidbr); | 
|  | 783   RRE_FORM(flogr); | 
|  | 784   RX_FORM(ic_z); | 
|  | 785   RXY_FORM(icy); | 
|  | 786   RIL1_FORM(iihf); | 
|  | 787   RI1_FORM(iihh); | 
|  | 788   RI1_FORM(iihl); | 
|  | 789   RIL1_FORM(iilf); | 
|  | 790   RI1_FORM(iilh); | 
|  | 791   RI1_FORM(iill); | 
|  | 792   RRE_FORM(lcgr); | 
|  | 793   RR_FORM(lcr); | 
|  | 794   RX_FORM(le_z); | 
|  | 795   RXY_FORM(ley); | 
|  | 796   RIL1_FORM(llihf); | 
|  | 797   RIL1_FORM(llilf); | 
|  | 798   RRE_FORM(lngr); | 
|  | 799   RR_FORM(lnr); | 
|  | 800   RSY1_FORM(loc); | 
|  | 801   RXY_FORM(lrv); | 
|  | 802   RXY_FORM(lrvh); | 
|  | 803   RXE_FORM(mdb); | 
|  | 804   RRE_FORM(mdbr); | 
|  | 805   SS4_FORM(mvck); | 
|  | 806   SSF_FORM(mvcos); | 
|  | 807   SS4_FORM(mvcs); | 
|  | 808   SS1_FORM(mvn); | 
|  | 809   SS1_FORM(nc); | 
|  | 810   SI_FORM(ni); | 
|  | 811   RIL1_FORM(nihf); | 
|  | 812   RIL1_FORM(nilf); | 
|  | 813   RI1_FORM(nilh); | 
|  | 814   RI1_FORM(nill); | 
|  | 815   RIL1_FORM(oihf); | 
|  | 816   RIL1_FORM(oilf); | 
|  | 817   RI1_FORM(oill); | 
|  | 818   RRE_FORM(popcnt); | 
|  | 819   RXE_FORM(sdb); | 
|  | 820   RRE_FORM(sdbr); | 
|  | 821   RIL1_FORM(slfi); | 
|  | 822   RXY_FORM(slgf); | 
|  | 823   RIL1_FORM(slgfi); | 
|  | 824   RS1_FORM(srdl); | 
|  | 825   RX_FORM(ste); | 
|  | 826   RXY_FORM(stey); | 
|  | 827   RXY_FORM(strv); | 
|  | 828   RI1_FORM(tmll); | 
|  | 829   SS1_FORM(tr); | 
|  | 830   S_FORM(ts); | 
|  | 831   RIL1_FORM(xihf); | 
|  | 832   RIL1_FORM(xilf); | 
|  | 833 | 
|  | 834   // Load Address Instructions | 
|  | 835   void la(Register r, const MemOperand& opnd); | 
|  | 836   void lay(Register r, const MemOperand& opnd); | 
|  | 837   void larl(Register r1, const Operand& opnd); | 
|  | 838   void larl(Register r, Label* l); | 
|  | 839 | 
|  | 840   // Load Instructions | 
|  | 841   void lb(Register r, const MemOperand& src); | 
|  | 842   void lbr(Register r1, Register r2); | 
|  | 843   void lgb(Register r, const MemOperand& src); | 
|  | 844   void lgbr(Register r1, Register r2); | 
|  | 845   void lh(Register r, const MemOperand& src); | 
|  | 846   void lhy(Register r, const MemOperand& src); | 
|  | 847   void lhr(Register r1, Register r2); | 
|  | 848   void lgh(Register r, const MemOperand& src); | 
|  | 849   void lghr(Register r1, Register r2); | 
|  | 850   void l(Register r, const MemOperand& src); | 
|  | 851   void ly(Register r, const MemOperand& src); | 
|  | 852   void lr(Register r1, Register r2); | 
|  | 853   void lg(Register r, const MemOperand& src); | 
|  | 854   void lgr(Register r1, Register r2); | 
|  | 855   void lgf(Register r, const MemOperand& src); | 
|  | 856   void lgfr(Register r1, Register r2); | 
|  | 857   void lhi(Register r, const Operand& imm); | 
|  | 858   void lghi(Register r, const Operand& imm); | 
|  | 859 | 
|  | 860   // Load And Test Instructions | 
|  | 861   void lt_z(Register r, const MemOperand& src); | 
|  | 862   void ltg(Register r, const MemOperand& src); | 
|  | 863   void ltr(Register r1, Register r2); | 
|  | 864   void ltgr(Register r1, Register r2); | 
|  | 865   void ltgfr(Register r1, Register r2); | 
|  | 866 | 
|  | 867   // Load Logical Instructions | 
|  | 868   void llc(Register r, const MemOperand& src); | 
|  | 869   void llgc(Register r, const MemOperand& src); | 
|  | 870   void llgf(Register r, const MemOperand& src); | 
|  | 871   void llgfr(Register r1, Register r2); | 
|  | 872   void llh(Register r, const MemOperand& src); | 
|  | 873   void llgh(Register r, const MemOperand& src); | 
|  | 874   void llhr(Register r1, Register r2); | 
|  | 875   void llghr(Register r1, Register r2); | 
|  | 876 | 
|  | 877   // Load Multiple Instructions | 
|  | 878   void lm(Register r1, Register r2, const MemOperand& src); | 
|  | 879   void lmy(Register r1, Register r2, const MemOperand& src); | 
|  | 880   void lmg(Register r1, Register r2, const MemOperand& src); | 
|  | 881 | 
|  | 882   // Store Instructions | 
|  | 883   void st(Register r, const MemOperand& src); | 
|  | 884   void stc(Register r, const MemOperand& src); | 
|  | 885   void stcy(Register r, const MemOperand& src); | 
|  | 886   void stg(Register r, const MemOperand& src); | 
|  | 887   void sth(Register r, const MemOperand& src); | 
|  | 888   void sthy(Register r, const MemOperand& src); | 
|  | 889   void sty(Register r, const MemOperand& src); | 
|  | 890 | 
|  | 891   // Store Multiple Instructions | 
|  | 892   void stm(Register r1, Register r2, const MemOperand& src); | 
|  | 893   void stmy(Register r1, Register r2, const MemOperand& src); | 
|  | 894   void stmg(Register r1, Register r2, const MemOperand& src); | 
|  | 895 | 
|  | 896   // Compare Instructions | 
|  | 897   void c(Register r, const MemOperand& opnd); | 
|  | 898   void cy(Register r, const MemOperand& opnd); | 
|  | 899   void cr_z(Register r1, Register r2); | 
|  | 900   void cg(Register r, const MemOperand& opnd); | 
|  | 901   void cgr(Register r1, Register r2); | 
|  | 902   void ch(Register r, const MemOperand& opnd); | 
|  | 903   void chy(Register r, const MemOperand& opnd); | 
|  | 904   void chi(Register r, const Operand& opnd); | 
|  | 905   void cghi(Register r, const Operand& opnd); | 
|  | 906   void cfi(Register r, const Operand& opnd); | 
|  | 907   void cgfi(Register r, const Operand& opnd); | 
|  | 908 | 
|  | 909   // Compare Logical Instructions | 
|  | 910   void cl(Register r, const MemOperand& opnd); | 
|  | 911   void cly(Register r, const MemOperand& opnd); | 
|  | 912   void clr(Register r1, Register r2); | 
|  | 913   void clg(Register r, const MemOperand& opnd); | 
|  | 914   void clgr(Register r1, Register r2); | 
|  | 915   void clfi(Register r, const Operand& opnd); | 
|  | 916   void clgfi(Register r, const Operand& opnd); | 
|  | 917   void cli(const MemOperand& mem, const Operand& imm); | 
|  | 918   void cliy(const MemOperand& mem, const Operand& imm); | 
|  | 919   void clc(const MemOperand& opnd1, const MemOperand& opnd2, Length length); | 
|  | 920 | 
|  | 921   // Test Under Mask Instructions | 
|  | 922   void tm(const MemOperand& mem, const Operand& imm); | 
|  | 923   void tmy(const MemOperand& mem, const Operand& imm); | 
|  | 924 | 
|  | 925   // Rotate Instructions | 
|  | 926   void rll(Register r1, Register r3, Register opnd); | 
|  | 927   void rll(Register r1, Register r3, const Operand& opnd); | 
|  | 928   void rll(Register r1, Register r3, Register r2, const Operand& opnd); | 
|  | 929   void rllg(Register r1, Register r3, const Operand& opnd); | 
|  | 930   void rllg(Register r1, Register r3, const Register opnd); | 
|  | 931   void rllg(Register r1, Register r3, Register r2, const Operand& opnd); | 
|  | 932 | 
|  | 933   // Shift Instructions (32) | 
|  | 934   void sll(Register r1, Register opnd); | 
|  | 935   void sll(Register r1, const Operand& opnd); | 
|  | 936   void sllk(Register r1, Register r3, Register opnd); | 
|  | 937   void sllk(Register r1, Register r3, const Operand& opnd); | 
|  | 938   void srl(Register r1, Register opnd); | 
|  | 939   void srl(Register r1, const Operand& opnd); | 
|  | 940   void srlk(Register r1, Register r3, Register opnd); | 
|  | 941   void srlk(Register r1, Register r3, const Operand& opnd); | 
|  | 942   void sra(Register r1, Register opnd); | 
|  | 943   void sra(Register r1, const Operand& opnd); | 
|  | 944   void srak(Register r1, Register r3, Register opnd); | 
|  | 945   void srak(Register r1, Register r3, const Operand& opnd); | 
|  | 946   void sla(Register r1, Register opnd); | 
|  | 947   void sla(Register r1, const Operand& opnd); | 
|  | 948   void slak(Register r1, Register r3, Register opnd); | 
|  | 949   void slak(Register r1, Register r3, const Operand& opnd); | 
|  | 950 | 
|  | 951   // Shift Instructions (64) | 
|  | 952   void sllg(Register r1, Register r3, const Operand& opnd); | 
|  | 953   void sllg(Register r1, Register r3, const Register opnd); | 
|  | 954   void srlg(Register r1, Register r3, const Operand& opnd); | 
|  | 955   void srlg(Register r1, Register r3, const Register opnd); | 
|  | 956   void srag(Register r1, Register r3, const Operand& opnd); | 
|  | 957   void srag(Register r1, Register r3, const Register opnd); | 
|  | 958   void srda(Register r1, const Operand& opnd); | 
|  | 959   void srdl(Register r1, const Operand& opnd); | 
|  | 960   void slag(Register r1, Register r3, const Operand& opnd); | 
|  | 961   void slag(Register r1, Register r3, const Register opnd); | 
|  | 962 | 
|  | 963   // Rotate and Insert Selected Bits | 
|  | 964   void risbg(Register dst, Register src, const Operand& startBit, | 
|  | 965              const Operand& endBit, const Operand& shiftAmt, | 
|  | 966              bool zeroBits = true); | 
|  | 967   void risbgn(Register dst, Register src, const Operand& startBit, | 
|  | 968               const Operand& endBit, const Operand& shiftAmt, | 
|  | 969               bool zeroBits = true); | 
|  | 970 | 
|  | 971   // Move Character (Mem to Mem) | 
|  | 972   void mvc(const MemOperand& opnd1, const MemOperand& opnd2, uint32_t length); | 
|  | 973 | 
|  | 974   // Branch Instructions | 
|  | 975   void basr(Register r1, Register r2); | 
|  | 976   void bcr(Condition m, Register target); | 
|  | 977   void bct(Register r, const MemOperand& opnd); | 
|  | 978   void bctg(Register r, const MemOperand& opnd); | 
|  | 979   void bras(Register r, const Operand& opnd); | 
|  | 980   void brasl(Register r, const Operand& opnd); | 
|  | 981   void brc(Condition c, const Operand& opnd); | 
|  | 982   void brcl(Condition m, const Operand& opnd, bool isCodeTarget = false); | 
|  | 983   void brct(Register r1, const Operand& opnd); | 
|  | 984   void brctg(Register r1, const Operand& opnd); | 
|  | 985 | 
|  | 986   // 32-bit Add Instructions | 
|  | 987   void a(Register r1, const MemOperand& opnd); | 
|  | 988   void ay(Register r1, const MemOperand& opnd); | 
|  | 989   void afi(Register r1, const Operand& opnd); | 
|  | 990   void ah(Register r1, const MemOperand& opnd); | 
|  | 991   void ahy(Register r1, const MemOperand& opnd); | 
|  | 992   void ahi(Register r1, const Operand& opnd); | 
|  | 993   void ahik(Register r1, Register r3, const Operand& opnd); | 
|  | 994   void ar(Register r1, Register r2); | 
|  | 995   void ark(Register r1, Register r2, Register r3); | 
|  | 996   void asi(const MemOperand&, const Operand&); | 
|  | 997 | 
|  | 998   // 64-bit Add Instructions | 
|  | 999   void ag(Register r1, const MemOperand& opnd); | 
|  | 1000   void agf(Register r1, const MemOperand& opnd); | 
|  | 1001   void agfi(Register r1, const Operand& opnd); | 
|  | 1002   void agfr(Register r1, Register r2); | 
|  | 1003   void aghi(Register r1, const Operand& opnd); | 
|  | 1004   void aghik(Register r1, Register r3, const Operand& opnd); | 
|  | 1005   void agr(Register r1, Register r2); | 
|  | 1006   void agrk(Register r1, Register r2, Register r3); | 
|  | 1007   void agsi(const MemOperand&, const Operand&); | 
|  | 1008 | 
|  | 1009   // 32-bit Add Logical Instructions | 
|  | 1010   void al_z(Register r1, const MemOperand& opnd); | 
|  | 1011   void aly(Register r1, const MemOperand& opnd); | 
|  | 1012   void alfi(Register r1, const Operand& opnd); | 
|  | 1013   void alr(Register r1, Register r2); | 
|  | 1014   void alrk(Register r1, Register r2, Register r3); | 
|  | 1015 | 
|  | 1016   // 64-bit Add Logical Instructions | 
|  | 1017   void alg(Register r1, const MemOperand& opnd); | 
|  | 1018   void algfi(Register r1, const Operand& opnd); | 
|  | 1019   void algr(Register r1, Register r2); | 
|  | 1020   void algrk(Register r1, Register r2, Register r3); | 
|  | 1021 | 
|  | 1022   // 32-bit Subtract Instructions | 
|  | 1023   void s(Register r1, const MemOperand& opnd); | 
|  | 1024   void sy(Register r1, const MemOperand& opnd); | 
|  | 1025   void sh(Register r1, const MemOperand& opnd); | 
|  | 1026   void shy(Register r1, const MemOperand& opnd); | 
|  | 1027   void sr(Register r1, Register r2); | 
|  | 1028   void srk(Register r1, Register r2, Register r3); | 
|  | 1029 | 
|  | 1030   // 64-bit Subtract Instructions | 
|  | 1031   void sg(Register r1, const MemOperand& opnd); | 
|  | 1032   void sgf(Register r1, const MemOperand& opnd); | 
|  | 1033   void sgr(Register r1, Register r2); | 
|  | 1034   void sgfr(Register r1, Register r2); | 
|  | 1035   void sgrk(Register r1, Register r2, Register r3); | 
|  | 1036 | 
|  | 1037   // 32-bit Subtract Logical Instructions | 
|  | 1038   void sl(Register r1, const MemOperand& opnd); | 
|  | 1039   void sly(Register r1, const MemOperand& opnd); | 
|  | 1040   void slr(Register r1, Register r2); | 
|  | 1041   void slrk(Register r1, Register r2, Register r3); | 
|  | 1042 | 
|  | 1043   // 64-bit Subtract Logical Instructions | 
|  | 1044   void slg(Register r1, const MemOperand& opnd); | 
|  | 1045   void slgr(Register r1, Register r2); | 
|  | 1046   void slgrk(Register r1, Register r2, Register r3); | 
|  | 1047 | 
|  | 1048   // 32-bit Multiply Instructions | 
|  | 1049   void m(Register r1, const MemOperand& opnd); | 
|  | 1050   void mr_z(Register r1, Register r2); | 
|  | 1051   void ml(Register r1, const MemOperand& opnd); | 
|  | 1052   void mlr(Register r1, Register r2); | 
|  | 1053   void ms(Register r1, const MemOperand& opnd); | 
|  | 1054   void msy(Register r1, const MemOperand& opnd); | 
|  | 1055   void msfi(Register r1, const Operand& opnd); | 
|  | 1056   void msr(Register r1, Register r2); | 
|  | 1057   void mh(Register r1, const MemOperand& opnd); | 
|  | 1058   void mhy(Register r1, const MemOperand& opnd); | 
|  | 1059   void mhi(Register r1, const Operand& opnd); | 
|  | 1060 | 
|  | 1061   // 64-bit Multiply Instructions | 
|  | 1062   void mlg(Register r1, const MemOperand& opnd); | 
|  | 1063   void mlgr(Register r1, Register r2); | 
|  | 1064   void mghi(Register r1, const Operand& opnd); | 
|  | 1065   void msgfi(Register r1, const Operand& opnd); | 
|  | 1066   void msg(Register r1, const MemOperand& opnd); | 
|  | 1067   void msgr(Register r1, Register r2); | 
|  | 1068 | 
|  | 1069   // 32-bit Divide Instructions | 
|  | 1070   void d(Register r1, const MemOperand& opnd); | 
|  | 1071   void dr(Register r1, Register r2); | 
|  | 1072   void dl(Register r1, const MemOperand& opnd); | 
|  | 1073   void dlr(Register r1, Register r2); | 
|  | 1074 | 
|  | 1075   // 64-bit Divide Instructions | 
|  | 1076   void dlgr(Register r1, Register r2); | 
|  | 1077   void dsgr(Register r1, Register r2); | 
|  | 1078 | 
|  | 1079   // Bitwise Instructions (AND / OR / XOR) | 
|  | 1080   void n(Register r1, const MemOperand& opnd); | 
|  | 1081   void ny(Register r1, const MemOperand& opnd); | 
|  | 1082   void nr(Register r1, Register r2); | 
|  | 1083   void nrk(Register r1, Register r2, Register r3); | 
|  | 1084   void ng(Register r1, const MemOperand& opnd); | 
|  | 1085   void ngr(Register r1, Register r2); | 
|  | 1086   void ngrk(Register r1, Register r2, Register r3); | 
|  | 1087   void o(Register r1, const MemOperand& opnd); | 
|  | 1088   void oy(Register r1, const MemOperand& opnd); | 
|  | 1089   void or_z(Register r1, Register r2); | 
|  | 1090   void ork(Register r1, Register r2, Register r3); | 
|  | 1091   void og(Register r1, const MemOperand& opnd); | 
|  | 1092   void ogr(Register r1, Register r2); | 
|  | 1093   void ogrk(Register r1, Register r2, Register r3); | 
|  | 1094   void x(Register r1, const MemOperand& opnd); | 
|  | 1095   void xy(Register r1, const MemOperand& opnd); | 
|  | 1096   void xr(Register r1, Register r2); | 
|  | 1097   void xrk(Register r1, Register r2, Register r3); | 
|  | 1098   void xg(Register r1, const MemOperand& opnd); | 
|  | 1099   void xgr(Register r1, Register r2); | 
|  | 1100   void xgrk(Register r1, Register r2, Register r3); | 
|  | 1101   void xc(const MemOperand& opnd1, const MemOperand& opnd2, Length length); | 
|  | 1102 | 
|  | 1103   // Bitwise GPR <-> FPR Conversion Instructions | 
|  | 1104   void lgdr(Register r1, DoubleRegister f2); | 
|  | 1105   void ldgr(DoubleRegister f1, Register r2); | 
|  | 1106 | 
|  | 1107   // Floating Point Load / Store Instructions | 
|  | 1108   void ld(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1109   void ldy(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1110   void le_z(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1111   void ley(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1112   void ldr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1113   void ltdbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1114   void ltebr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1115   void std(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1116   void stdy(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1117   void ste(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1118   void stey(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1119 | 
|  | 1120   // Floating Point Load Rounded/Positive Instructions | 
|  | 1121   void ledbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1122   void ldebr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1123   void lpebr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1124   void lpdbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1125 | 
|  | 1126   // Floating <-> Fixed Point Conversion Instructions | 
|  | 1127   void cdlfbr(Condition m3, Condition m4, DoubleRegister fltReg, | 
|  | 1128               Register fixReg); | 
|  | 1129   void cdlgbr(Condition m3, Condition m4, DoubleRegister fltReg, | 
|  | 1130               Register fixReg); | 
|  | 1131   void celgbr(Condition m3, Condition m4, DoubleRegister fltReg, | 
|  | 1132               Register fixReg); | 
|  | 1133   void celfbr(Condition m3, Condition m4, DoubleRegister fltReg, | 
|  | 1134               Register fixReg); | 
|  | 1135   void clfdbr(Condition m3, Condition m4, Register fixReg, | 
|  | 1136               DoubleRegister fltReg); | 
|  | 1137   void clfebr(Condition m3, Condition m4, Register fixReg, | 
|  | 1138               DoubleRegister fltReg); | 
|  | 1139   void clgdbr(Condition m3, Condition m4, Register fixReg, | 
|  | 1140               DoubleRegister fltReg); | 
|  | 1141   void clgebr(Condition m3, Condition m4, Register fixReg, | 
|  | 1142               DoubleRegister fltReg); | 
|  | 1143   void cfdbr(Condition m, Register fixReg, DoubleRegister fltReg); | 
|  | 1144   void cdfbr(DoubleRegister fltReg, Register fixReg); | 
|  | 1145   void cgebr(Condition m, Register fixReg, DoubleRegister fltReg); | 
|  | 1146   void cgdbr(Condition m, Register fixReg, DoubleRegister fltReg); | 
|  | 1147   void cegbr(DoubleRegister fltReg, Register fixReg); | 
|  | 1148   void cdgbr(DoubleRegister fltReg, Register fixReg); | 
|  | 1149   void cfebr(Condition m3, Register fixReg, DoubleRegister fltReg); | 
|  | 1150   void cefbr(DoubleRegister fltReg, Register fixReg); | 
|  | 1151 | 
|  | 1152   // Floating Point Compare Instructions | 
|  | 1153   void cebr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1154   void cdb(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1155   void cdbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1156 | 
|  | 1157   // Floating Point Arithmetic Instructions | 
|  | 1158   void aebr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1159   void adb(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1160   void adbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1161   void lzdr(DoubleRegister r1); | 
|  | 1162   void sebr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1163   void sdb(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1164   void sdbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1165   void meebr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1166   void mdb(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1167   void mdbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1168   void debr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1169   void ddb(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1170   void ddbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1171   void madbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3); | 
|  | 1172   void msdbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3); | 
|  | 1173   void sqebr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1174   void sqdb(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1175   void sqdbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1176   void lcdbr(DoubleRegister r1, DoubleRegister r2); | 
|  | 1177   void ldeb(DoubleRegister r1, const MemOperand& opnd); | 
|  | 1178 | 
|  | 1179   enum FIDBRA_MASK3 { | 
|  | 1180     FIDBRA_CURRENT_ROUNDING_MODE = 0, | 
|  | 1181     FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0 = 1, | 
|  | 1182     // ... | 
|  | 1183     FIDBRA_ROUND_TOWARD_0 = 5, | 
|  | 1184     FIDBRA_ROUND_TOWARD_POS_INF = 6, | 
|  | 1185     FIDBRA_ROUND_TOWARD_NEG_INF = 7 | 
|  | 1186   }; | 
|  | 1187   void fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3); | 
|  | 1188   void fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3); | 
|  | 1189 | 
|  | 1190   // Move integer | 
|  | 1191   void mvhi(const MemOperand& opnd1, const Operand& i2); | 
|  | 1192   void mvghi(const MemOperand& opnd1, const Operand& i2); | 
|  | 1193 | 
|  | 1194   // Exception-generating instructions and debugging support | 
|  | 1195   void stop(const char* msg, Condition cond = al, | 
|  | 1196             int32_t code = kDefaultStopCode, CRegister cr = cr7); | 
|  | 1197 | 
|  | 1198   void bkpt(uint32_t imm16);  // v5 and above | 
|  | 1199 | 
|  | 1200   // Different nop operations are used by the code generator to detect certain | 
|  | 1201   // states of the generated code. | 
|  | 1202   enum NopMarkerTypes { | 
|  | 1203     NON_MARKING_NOP = 0, | 
|  | 1204     GROUP_ENDING_NOP, | 
|  | 1205     DEBUG_BREAK_NOP, | 
|  | 1206     // IC markers. | 
|  | 1207     PROPERTY_ACCESS_INLINED, | 
|  | 1208     PROPERTY_ACCESS_INLINED_CONTEXT, | 
|  | 1209     PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE, | 
|  | 1210     // Helper values. | 
|  | 1211     LAST_CODE_MARKER, | 
|  | 1212     FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED | 
|  | 1213   }; | 
|  | 1214 | 
|  | 1215   void nop(int type = 0);  // 0 is the default non-marking type. | 
|  | 1216 | 
|  | 1217   // Check the code size generated from label to here. | 
|  | 1218   int SizeOfCodeGeneratedSince(Label* label) { | 
|  | 1219     return pc_offset() - label->pos(); | 
|  | 1220   } | 
|  | 1221 | 
|  | 1222   // Debugging | 
|  | 1223 | 
|  | 1224   // Mark generator continuation. | 
|  | 1225   void RecordGeneratorContinuation(); | 
|  | 1226 | 
|  | 1227   // Mark address of a debug break slot. | 
|  | 1228   void RecordDebugBreakSlot(RelocInfo::Mode mode); | 
|  | 1229 | 
|  | 1230   // Record the AST id of the CallIC being compiled, so that it can be placed | 
|  | 1231   // in the relocation information. | 
|  | 1232   void SetRecordedAstId(TypeFeedbackId ast_id) { recorded_ast_id_ = ast_id; } | 
|  | 1233 | 
|  | 1234   TypeFeedbackId RecordedAstId() { | 
|  | 1235     // roohack - another issue??? DCHECK(!recorded_ast_id_.IsNone()); | 
|  | 1236     return recorded_ast_id_; | 
|  | 1237   } | 
|  | 1238 | 
|  | 1239   void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); } | 
|  | 1240 | 
|  | 1241   // Record a comment relocation entry that can be used by a disassembler. | 
|  | 1242   // Use --code-comments to enable. | 
|  | 1243   void RecordComment(const char* msg); | 
|  | 1244 | 
|  | 1245   // Record a deoptimization reason that can be used by a log or cpu profiler. | 
|  | 1246   // Use --trace-deopt to enable. | 
|  | 1247   void RecordDeoptReason(const int reason, int raw_position); | 
|  | 1248 | 
|  | 1249   // Writes a single byte or word of data in the code stream.  Used | 
|  | 1250   // for inline tables, e.g., jump-tables. | 
|  | 1251   void db(uint8_t data); | 
|  | 1252   void dd(uint32_t data); | 
|  | 1253   void dq(uint64_t data); | 
|  | 1254   void dp(uintptr_t data); | 
|  | 1255 | 
|  | 1256   PositionsRecorder* positions_recorder() { return &positions_recorder_; } | 
|  | 1257 | 
|  | 1258   void PatchConstantPoolAccessInstruction(int pc_offset, int offset, | 
|  | 1259                                           ConstantPoolEntry::Access access, | 
|  | 1260                                           ConstantPoolEntry::Type type) { | 
|  | 1261     // No embedded constant pool support. | 
|  | 1262     UNREACHABLE(); | 
|  | 1263   } | 
|  | 1264 | 
|  | 1265   // Read/patch instructions | 
|  | 1266   SixByteInstr instr_at(int pos) { | 
|  | 1267     return Instruction::InstructionBits(buffer_ + pos); | 
|  | 1268   } | 
|  | 1269   template <typename T> | 
|  | 1270   void instr_at_put(int pos, T instr) { | 
|  | 1271     Instruction::SetInstructionBits<T>(buffer_ + pos, instr); | 
|  | 1272   } | 
|  | 1273 | 
|  | 1274   // Decodes instruction at pos, and returns its length | 
|  | 1275   int32_t instr_length_at(int pos) { | 
|  | 1276     return Instruction::InstructionLength(buffer_ + pos); | 
|  | 1277   } | 
|  | 1278 | 
|  | 1279   static SixByteInstr instr_at(byte* pc) { | 
|  | 1280     return Instruction::InstructionBits(pc); | 
|  | 1281   } | 
|  | 1282 | 
|  | 1283   static Condition GetCondition(Instr instr); | 
|  | 1284 | 
|  | 1285   static bool IsBranch(Instr instr); | 
|  | 1286 #if V8_TARGET_ARCH_S390X | 
|  | 1287   static bool Is64BitLoadIntoIP(SixByteInstr instr1, SixByteInstr instr2); | 
|  | 1288 #else | 
|  | 1289   static bool Is32BitLoadIntoIP(SixByteInstr instr); | 
|  | 1290 #endif | 
|  | 1291 | 
|  | 1292   static bool IsCmpRegister(Instr instr); | 
|  | 1293   static bool IsCmpImmediate(Instr instr); | 
|  | 1294   static bool IsNop(SixByteInstr instr, int type = NON_MARKING_NOP); | 
|  | 1295 | 
|  | 1296   // The code currently calls CheckBuffer() too often. This has the side | 
|  | 1297   // effect of randomly growing the buffer in the middle of multi-instruction | 
|  | 1298   // sequences. | 
|  | 1299   // | 
|  | 1300   // This function allows outside callers to check and grow the buffer | 
|  | 1301   void EnsureSpaceFor(int space_needed); | 
|  | 1302 | 
|  | 1303   void EmitRelocations(); | 
|  | 1304   void emit_label_addr(Label* label); | 
|  | 1305 | 
|  | 1306  public: | 
|  | 1307   byte* buffer_pos() const { return buffer_; } | 
|  | 1308 | 
|  | 1309  protected: | 
|  | 1310   // Relocation for a type-recording IC has the AST id added to it.  This | 
|  | 1311   // member variable is a way to pass the information from the call site to | 
|  | 1312   // the relocation info. | 
|  | 1313   TypeFeedbackId recorded_ast_id_; | 
|  | 1314 | 
|  | 1315   int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 
|  | 1316 | 
|  | 1317   // Decode instruction(s) at pos and return backchain to previous | 
|  | 1318   // label reference or kEndOfChain. | 
|  | 1319   int target_at(int pos); | 
|  | 1320 | 
|  | 1321   // Patch instruction(s) at pos to target target_pos (e.g. branch) | 
|  | 1322   void target_at_put(int pos, int target_pos, bool* is_branch = nullptr); | 
|  | 1323 | 
|  | 1324   // Record reloc info for current pc_ | 
|  | 1325   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 
|  | 1326 | 
|  | 1327  private: | 
|  | 1328   // Code generation | 
|  | 1329   // The relocation writer's position is at least kGap bytes below the end of | 
|  | 1330   // the generated instructions. This is so that multi-instruction sequences do | 
|  | 1331   // not have to check for overflow. The same is true for writes of large | 
|  | 1332   // relocation info entries. | 
|  | 1333   static const int kGap = 32; | 
|  | 1334 | 
|  | 1335   // Relocation info generation | 
|  | 1336   // Each relocation is encoded as a variable size value | 
|  | 1337   static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 
|  | 1338   RelocInfoWriter reloc_info_writer; | 
|  | 1339   std::vector<DeferredRelocInfo> relocations_; | 
|  | 1340 | 
|  | 1341   // The bound position, before this we cannot do instruction elimination. | 
|  | 1342   int last_bound_pos_; | 
|  | 1343 | 
|  | 1344   // Code emission | 
|  | 1345   inline void CheckBuffer(); | 
|  | 1346   void GrowBuffer(int needed = 0); | 
|  | 1347   inline void TrackBranch(); | 
|  | 1348   inline void UntrackBranch(); | 
|  | 1349 | 
|  | 1350   inline int32_t emit_code_target( | 
|  | 1351       Handle<Code> target, RelocInfo::Mode rmode, | 
|  | 1352       TypeFeedbackId ast_id = TypeFeedbackId::None()); | 
|  | 1353 | 
|  | 1354   // Helpers to emit binary encoding of 2/4/6 byte instructions. | 
|  | 1355   inline void emit2bytes(uint16_t x); | 
|  | 1356   inline void emit4bytes(uint32_t x); | 
|  | 1357   inline void emit6bytes(uint64_t x); | 
|  | 1358 | 
|  | 1359   // Helpers to emit binary encoding for various instruction formats. | 
|  | 1360 | 
|  | 1361   inline void rr_form(Opcode op, Register r1, Register r2); | 
|  | 1362   inline void rr_form(Opcode op, DoubleRegister r1, DoubleRegister r2); | 
|  | 1363   inline void rr_form(Opcode op, Condition m1, Register r2); | 
|  | 1364   inline void rr2_form(uint8_t op, Condition m1, Register r2); | 
|  | 1365 | 
|  | 1366   inline void rx_form(Opcode op, Register r1, Register x2, Register b2, | 
|  | 1367                       Disp d2); | 
|  | 1368   inline void rx_form(Opcode op, DoubleRegister r1, Register x2, Register b2, | 
|  | 1369                       Disp d2); | 
|  | 1370 | 
|  | 1371   inline void ri_form(Opcode op, Register r1, const Operand& i2); | 
|  | 1372   inline void ri_form(Opcode op, Condition m1, const Operand& i2); | 
|  | 1373 | 
|  | 1374   inline void rie_form(Opcode op, Register r1, Register r3, const Operand& i2); | 
|  | 1375   inline void rie_f_form(Opcode op, Register r1, Register r2, const Operand& i3, | 
|  | 1376                          const Operand& i4, const Operand& i5); | 
|  | 1377 | 
|  | 1378   inline void ril_form(Opcode op, Register r1, const Operand& i2); | 
|  | 1379   inline void ril_form(Opcode op, Condition m1, const Operand& i2); | 
|  | 1380 | 
|  | 1381   inline void ris_form(Opcode op, Register r1, Condition m3, Register b4, | 
|  | 1382                        Disp d4, const Operand& i2); | 
|  | 1383 | 
|  | 1384   inline void rrd_form(Opcode op, Register r1, Register r3, Register r2); | 
|  | 1385 | 
|  | 1386   inline void rre_form(Opcode op, Register r1, Register r2); | 
|  | 1387   inline void rre_form(Opcode op, DoubleRegister r1, DoubleRegister r2); | 
|  | 1388 | 
|  | 1389   inline void rrf1_form(Opcode op, Register r1, Register r2, Register r3); | 
|  | 1390   inline void rrf1_form(uint32_t x); | 
|  | 1391   inline void rrf2_form(uint32_t x); | 
|  | 1392   inline void rrf3_form(uint32_t x); | 
|  | 1393   inline void rrfe_form(Opcode op, Condition m3, Condition m4, Register r1, | 
|  | 1394                         Register r2); | 
|  | 1395 | 
|  | 1396   inline void rrs_form(Opcode op, Register r1, Register r2, Register b4, | 
|  | 1397                        Disp d4, Condition m3); | 
|  | 1398 | 
|  | 1399   inline void rs_form(Opcode op, Register r1, Condition m3, Register b2, | 
|  | 1400                       const Disp d2); | 
|  | 1401   inline void rs_form(Opcode op, Register r1, Register r3, Register b2, | 
|  | 1402                       const Disp d2); | 
|  | 1403 | 
|  | 1404   inline void rsi_form(Opcode op, Register r1, Register r3, const Operand& i2); | 
|  | 1405   inline void rsl_form(Opcode op, Length l1, Register b2, Disp d2); | 
|  | 1406 | 
|  | 1407   inline void rsy_form(Opcode op, Register r1, Register r3, Register b2, | 
|  | 1408                        const Disp d2); | 
|  | 1409   inline void rsy_form(Opcode op, Register r1, Condition m3, Register b2, | 
|  | 1410                        const Disp d2); | 
|  | 1411 | 
|  | 1412   inline void rxe_form(Opcode op, Register r1, Register x2, Register b2, | 
|  | 1413                        Disp d2); | 
|  | 1414 | 
|  | 1415   inline void rxf_form(Opcode op, Register r1, Register r3, Register b2, | 
|  | 1416                        Register x2, Disp d2); | 
|  | 1417 | 
|  | 1418   inline void rxy_form(Opcode op, Register r1, Register x2, Register b2, | 
|  | 1419                        Disp d2); | 
|  | 1420   inline void rxy_form(Opcode op, DoubleRegister r1, Register x2, Register b2, | 
|  | 1421                        Disp d2); | 
|  | 1422 | 
|  | 1423   inline void s_form(Opcode op, Register b1, Disp d2); | 
|  | 1424 | 
|  | 1425   inline void si_form(Opcode op, const Operand& i2, Register b1, Disp d1); | 
|  | 1426   inline void siy_form(Opcode op, const Operand& i2, Register b1, Disp d1); | 
|  | 1427 | 
|  | 1428   inline void sil_form(Opcode op, Register b1, Disp d1, const Operand& i2); | 
|  | 1429 | 
|  | 1430   inline void ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2, | 
|  | 1431                       Disp d2); | 
|  | 1432   inline void ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1, | 
|  | 1433                       Register b2, Disp d2); | 
|  | 1434   inline void ss_form(Opcode op, Length l1, const Operand& i3, Register b1, | 
|  | 1435                       Disp d1, Register b2, Disp d2); | 
|  | 1436   inline void ss_form(Opcode op, Register r1, Register r2, Register b1, Disp d1, | 
|  | 1437                       Register b2, Disp d2); | 
|  | 1438   inline void sse_form(Opcode op, Register b1, Disp d1, Register b2, Disp d2); | 
|  | 1439   inline void ssf_form(Opcode op, Register r3, Register b1, Disp d1, | 
|  | 1440                        Register b2, Disp d2); | 
|  | 1441 | 
|  | 1442   // Labels | 
|  | 1443   void print(Label* L); | 
|  | 1444   int max_reach_from(int pos); | 
|  | 1445   void bind_to(Label* L, int pos); | 
|  | 1446   void next(Label* L); | 
|  | 1447 | 
|  | 1448   friend class RegExpMacroAssemblerS390; | 
|  | 1449   friend class RelocInfo; | 
|  | 1450   friend class CodePatcher; | 
|  | 1451 | 
|  | 1452   List<Handle<Code> > code_targets_; | 
|  | 1453 | 
|  | 1454   PositionsRecorder positions_recorder_; | 
|  | 1455   friend class PositionsRecorder; | 
|  | 1456   friend class EnsureSpace; | 
|  | 1457 }; | 
|  | 1458 | 
|  | 1459 class EnsureSpace BASE_EMBEDDED { | 
|  | 1460  public: | 
|  | 1461   explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } | 
|  | 1462 }; | 
|  | 1463 | 
|  | 1464 }  // namespace internal | 
|  | 1465 }  // namespace v8 | 
|  | 1466 | 
|  | 1467 #endif  // V8_S390_ASSEMBLER_S390_H_ | 
| OLD | NEW | 
|---|