1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/ppc/vm/assembler_ppc.hpp Fri Aug 02 16:46:45 2013 +0200 1.3 @@ -0,0 +1,1963 @@ 1.4 +/* 1.5 + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright 2012, 2013 SAP AG. All rights reserved. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + * 1.27 + */ 1.28 + 1.29 +#ifndef CPU_PPC_VM_ASSEMBLER_PPC_HPP 1.30 +#define CPU_PPC_VM_ASSEMBLER_PPC_HPP 1.31 + 1.32 +#include "asm/register.hpp" 1.33 + 1.34 +// Address is an abstraction used to represent a memory location 1.35 +// as used in assembler instructions. 1.36 +// PPC instructions grok either baseReg + indexReg or baseReg + disp. 1.37 +// So far we do not use this as simplification by this class is low 1.38 +// on PPC with its simple addressing mode. Use RegisterOrConstant to 1.39 +// represent an offset. 1.40 +class Address VALUE_OBJ_CLASS_SPEC { 1.41 +}; 1.42 + 1.43 +class AddressLiteral VALUE_OBJ_CLASS_SPEC { 1.44 + private: 1.45 + address _address; 1.46 + RelocationHolder _rspec; 1.47 + 1.48 + RelocationHolder rspec_from_rtype(relocInfo::relocType rtype, address addr) { 1.49 + switch (rtype) { 1.50 + case relocInfo::external_word_type: 1.51 + return external_word_Relocation::spec(addr); 1.52 + case relocInfo::internal_word_type: 1.53 + return internal_word_Relocation::spec(addr); 1.54 + case relocInfo::opt_virtual_call_type: 1.55 + return opt_virtual_call_Relocation::spec(); 1.56 + case relocInfo::static_call_type: 1.57 + return static_call_Relocation::spec(); 1.58 + case relocInfo::runtime_call_type: 1.59 + return runtime_call_Relocation::spec(); 1.60 + case relocInfo::none: 1.61 + return RelocationHolder(); 1.62 + default: 1.63 + ShouldNotReachHere(); 1.64 + return RelocationHolder(); 1.65 + } 1.66 + } 1.67 + 1.68 + protected: 1.69 + // creation 1.70 + AddressLiteral() : _address(NULL), _rspec(NULL) {} 1.71 + 1.72 + public: 1.73 + AddressLiteral(address addr, RelocationHolder const& rspec) 1.74 + : _address(addr), 1.75 + _rspec(rspec) {} 1.76 + 1.77 + AddressLiteral(address addr, relocInfo::relocType rtype = relocInfo::none) 1.78 + : _address((address) addr), 1.79 + _rspec(rspec_from_rtype(rtype, (address) addr)) {} 1.80 + 1.81 + AddressLiteral(oop* addr, relocInfo::relocType rtype = relocInfo::none) 1.82 + : _address((address) addr), 1.83 + _rspec(rspec_from_rtype(rtype, (address) addr)) {} 1.84 + 1.85 + intptr_t value() const { return (intptr_t) _address; } 1.86 + 1.87 + const RelocationHolder& rspec() const { return _rspec; } 1.88 +}; 1.89 + 1.90 +// Argument is an abstraction used to represent an outgoing 1.91 +// actual argument or an incoming formal parameter, whether 1.92 +// it resides in memory or in a register, in a manner consistent 1.93 +// with the PPC Application Binary Interface, or ABI. This is 1.94 +// often referred to as the native or C calling convention. 1.95 + 1.96 +class Argument VALUE_OBJ_CLASS_SPEC { 1.97 + private: 1.98 + int _number; // The number of the argument. 1.99 + public: 1.100 + enum { 1.101 + // Only 8 registers may contain integer parameters. 1.102 + n_register_parameters = 8, 1.103 + // Can have up to 8 floating registers. 1.104 + n_float_register_parameters = 8 1.105 + }; 1.106 + // creation 1.107 + Argument(int number) : _number(number) {} 1.108 + 1.109 + int number() const { return _number; } 1.110 + 1.111 + // Locating register-based arguments: 1.112 + bool is_register() const { return _number < n_register_parameters; } 1.113 + 1.114 + Register as_register() const { 1.115 + assert(is_register(), "must be a register argument"); 1.116 + return as_Register(number() + R3_ARG1->encoding()); 1.117 + } 1.118 +}; 1.119 + 1.120 +// A ppc64 function descriptor. 1.121 +struct FunctionDescriptor VALUE_OBJ_CLASS_SPEC { 1.122 + private: 1.123 + address _entry; 1.124 + address _toc; 1.125 + address _env; 1.126 + 1.127 + public: 1.128 + inline address entry() const { return _entry; } 1.129 + inline address toc() const { return _toc; } 1.130 + inline address env() const { return _env; } 1.131 + 1.132 + inline void set_entry(address entry) { _entry = entry; } 1.133 + inline void set_toc( address toc) { _toc = toc; } 1.134 + inline void set_env( address env) { _env = env; } 1.135 + 1.136 + inline static ByteSize entry_offset() { return byte_offset_of(FunctionDescriptor, _entry); } 1.137 + inline static ByteSize toc_offset() { return byte_offset_of(FunctionDescriptor, _toc); } 1.138 + inline static ByteSize env_offset() { return byte_offset_of(FunctionDescriptor, _env); } 1.139 + 1.140 + // Friend functions can be called without loading toc and env. 1.141 + enum { 1.142 + friend_toc = 0xcafe, 1.143 + friend_env = 0xc0de 1.144 + }; 1.145 + 1.146 + inline bool is_friend_function() const { 1.147 + return (toc() == (address) friend_toc) && (env() == (address) friend_env); 1.148 + } 1.149 + 1.150 + // Constructor for stack-allocated instances. 1.151 + FunctionDescriptor() { 1.152 + _entry = (address) 0xbad; 1.153 + _toc = (address) 0xbad; 1.154 + _env = (address) 0xbad; 1.155 + } 1.156 +}; 1.157 + 1.158 +class Assembler : public AbstractAssembler { 1.159 + protected: 1.160 + // Displacement routines 1.161 + static void print_instruction(int inst); 1.162 + static int patched_branch(int dest_pos, int inst, int inst_pos); 1.163 + static int branch_destination(int inst, int pos); 1.164 + 1.165 + friend class AbstractAssembler; 1.166 + 1.167 + // Code patchers need various routines like inv_wdisp() 1.168 + friend class NativeInstruction; 1.169 + friend class NativeGeneralJump; 1.170 + friend class Relocation; 1.171 + 1.172 + public: 1.173 + 1.174 + enum shifts { 1.175 + XO_21_29_SHIFT = 2, 1.176 + XO_21_30_SHIFT = 1, 1.177 + XO_27_29_SHIFT = 2, 1.178 + XO_30_31_SHIFT = 0, 1.179 + SPR_5_9_SHIFT = 11u, // SPR_5_9 field in bits 11 -- 15 1.180 + SPR_0_4_SHIFT = 16u, // SPR_0_4 field in bits 16 -- 20 1.181 + RS_SHIFT = 21u, // RS field in bits 21 -- 25 1.182 + OPCODE_SHIFT = 26u, // opcode in bits 26 -- 31 1.183 + }; 1.184 + 1.185 + enum opcdxos_masks { 1.186 + XL_FORM_OPCODE_MASK = (63u << OPCODE_SHIFT) | (1023u << 1), 1.187 + ADDI_OPCODE_MASK = (63u << OPCODE_SHIFT), 1.188 + ADDIS_OPCODE_MASK = (63u << OPCODE_SHIFT), 1.189 + BXX_OPCODE_MASK = (63u << OPCODE_SHIFT), 1.190 + BCXX_OPCODE_MASK = (63u << OPCODE_SHIFT), 1.191 + // trap instructions 1.192 + TDI_OPCODE_MASK = (63u << OPCODE_SHIFT), 1.193 + TWI_OPCODE_MASK = (63u << OPCODE_SHIFT), 1.194 + TD_OPCODE_MASK = (63u << OPCODE_SHIFT) | (1023u << 1), 1.195 + TW_OPCODE_MASK = (63u << OPCODE_SHIFT) | (1023u << 1), 1.196 + LD_OPCODE_MASK = (63u << OPCODE_SHIFT) | (3u << XO_30_31_SHIFT), // DS-FORM 1.197 + STD_OPCODE_MASK = LD_OPCODE_MASK, 1.198 + STDU_OPCODE_MASK = STD_OPCODE_MASK, 1.199 + STDX_OPCODE_MASK = (63u << OPCODE_SHIFT) | (1023u << 1), 1.200 + STDUX_OPCODE_MASK = STDX_OPCODE_MASK, 1.201 + STW_OPCODE_MASK = (63u << OPCODE_SHIFT), 1.202 + STWU_OPCODE_MASK = STW_OPCODE_MASK, 1.203 + STWX_OPCODE_MASK = (63u << OPCODE_SHIFT) | (1023u << 1), 1.204 + STWUX_OPCODE_MASK = STWX_OPCODE_MASK, 1.205 + MTCTR_OPCODE_MASK = ~(31u << RS_SHIFT), 1.206 + ORI_OPCODE_MASK = (63u << OPCODE_SHIFT), 1.207 + ORIS_OPCODE_MASK = (63u << OPCODE_SHIFT), 1.208 + RLDICR_OPCODE_MASK = (63u << OPCODE_SHIFT) | (7u << XO_27_29_SHIFT) 1.209 + }; 1.210 + 1.211 + enum opcdxos { 1.212 + ADD_OPCODE = (31u << OPCODE_SHIFT | 266u << 1), 1.213 + ADDC_OPCODE = (31u << OPCODE_SHIFT | 10u << 1), 1.214 + ADDI_OPCODE = (14u << OPCODE_SHIFT), 1.215 + ADDIS_OPCODE = (15u << OPCODE_SHIFT), 1.216 + ADDIC__OPCODE = (13u << OPCODE_SHIFT), 1.217 + ADDE_OPCODE = (31u << OPCODE_SHIFT | 138u << 1), 1.218 + SUBF_OPCODE = (31u << OPCODE_SHIFT | 40u << 1), 1.219 + SUBFC_OPCODE = (31u << OPCODE_SHIFT | 8u << 1), 1.220 + SUBFE_OPCODE = (31u << OPCODE_SHIFT | 136u << 1), 1.221 + SUBFIC_OPCODE = (8u << OPCODE_SHIFT), 1.222 + SUBFZE_OPCODE = (31u << OPCODE_SHIFT | 200u << 1), 1.223 + DIVW_OPCODE = (31u << OPCODE_SHIFT | 491u << 1), 1.224 + MULLW_OPCODE = (31u << OPCODE_SHIFT | 235u << 1), 1.225 + MULHW_OPCODE = (31u << OPCODE_SHIFT | 75u << 1), 1.226 + MULHWU_OPCODE = (31u << OPCODE_SHIFT | 11u << 1), 1.227 + MULLI_OPCODE = (7u << OPCODE_SHIFT), 1.228 + AND_OPCODE = (31u << OPCODE_SHIFT | 28u << 1), 1.229 + ANDI_OPCODE = (28u << OPCODE_SHIFT), 1.230 + ANDIS_OPCODE = (29u << OPCODE_SHIFT), 1.231 + ANDC_OPCODE = (31u << OPCODE_SHIFT | 60u << 1), 1.232 + ORC_OPCODE = (31u << OPCODE_SHIFT | 412u << 1), 1.233 + OR_OPCODE = (31u << OPCODE_SHIFT | 444u << 1), 1.234 + ORI_OPCODE = (24u << OPCODE_SHIFT), 1.235 + ORIS_OPCODE = (25u << OPCODE_SHIFT), 1.236 + XOR_OPCODE = (31u << OPCODE_SHIFT | 316u << 1), 1.237 + XORI_OPCODE = (26u << OPCODE_SHIFT), 1.238 + XORIS_OPCODE = (27u << OPCODE_SHIFT), 1.239 + 1.240 + NEG_OPCODE = (31u << OPCODE_SHIFT | 104u << 1), 1.241 + 1.242 + RLWINM_OPCODE = (21u << OPCODE_SHIFT), 1.243 + CLRRWI_OPCODE = RLWINM_OPCODE, 1.244 + CLRLWI_OPCODE = RLWINM_OPCODE, 1.245 + 1.246 + RLWIMI_OPCODE = (20u << OPCODE_SHIFT), 1.247 + 1.248 + SLW_OPCODE = (31u << OPCODE_SHIFT | 24u << 1), 1.249 + SLWI_OPCODE = RLWINM_OPCODE, 1.250 + SRW_OPCODE = (31u << OPCODE_SHIFT | 536u << 1), 1.251 + SRWI_OPCODE = RLWINM_OPCODE, 1.252 + SRAW_OPCODE = (31u << OPCODE_SHIFT | 792u << 1), 1.253 + SRAWI_OPCODE = (31u << OPCODE_SHIFT | 824u << 1), 1.254 + 1.255 + CMP_OPCODE = (31u << OPCODE_SHIFT | 0u << 1), 1.256 + CMPI_OPCODE = (11u << OPCODE_SHIFT), 1.257 + CMPL_OPCODE = (31u << OPCODE_SHIFT | 32u << 1), 1.258 + CMPLI_OPCODE = (10u << OPCODE_SHIFT), 1.259 + 1.260 + ISEL_OPCODE = (31u << OPCODE_SHIFT | 15u << 1), 1.261 + 1.262 + MTLR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1 | 8 << SPR_0_4_SHIFT), 1.263 + MFLR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1 | 8 << SPR_0_4_SHIFT), 1.264 + 1.265 + MTCRF_OPCODE = (31u << OPCODE_SHIFT | 144u << 1), 1.266 + MFCR_OPCODE = (31u << OPCODE_SHIFT | 19u << 1), 1.267 + MCRF_OPCODE = (19u << OPCODE_SHIFT | 0u << 1), 1.268 + 1.269 + // condition register logic instructions 1.270 + CRAND_OPCODE = (19u << OPCODE_SHIFT | 257u << 1), 1.271 + CRNAND_OPCODE = (19u << OPCODE_SHIFT | 225u << 1), 1.272 + CROR_OPCODE = (19u << OPCODE_SHIFT | 449u << 1), 1.273 + CRXOR_OPCODE = (19u << OPCODE_SHIFT | 193u << 1), 1.274 + CRNOR_OPCODE = (19u << OPCODE_SHIFT | 33u << 1), 1.275 + CREQV_OPCODE = (19u << OPCODE_SHIFT | 289u << 1), 1.276 + CRANDC_OPCODE = (19u << OPCODE_SHIFT | 129u << 1), 1.277 + CRORC_OPCODE = (19u << OPCODE_SHIFT | 417u << 1), 1.278 + 1.279 + BCLR_OPCODE = (19u << OPCODE_SHIFT | 16u << 1), 1.280 + BXX_OPCODE = (18u << OPCODE_SHIFT), 1.281 + BCXX_OPCODE = (16u << OPCODE_SHIFT), 1.282 + 1.283 + // CTR-related opcodes 1.284 + BCCTR_OPCODE = (19u << OPCODE_SHIFT | 528u << 1), 1.285 + MTCTR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1 | 9 << SPR_0_4_SHIFT), 1.286 + MFCTR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1 | 9 << SPR_0_4_SHIFT), 1.287 + 1.288 + 1.289 + LWZ_OPCODE = (32u << OPCODE_SHIFT), 1.290 + LWZX_OPCODE = (31u << OPCODE_SHIFT | 23u << 1), 1.291 + LWZU_OPCODE = (33u << OPCODE_SHIFT), 1.292 + 1.293 + LHA_OPCODE = (42u << OPCODE_SHIFT), 1.294 + LHAX_OPCODE = (31u << OPCODE_SHIFT | 343u << 1), 1.295 + LHAU_OPCODE = (43u << OPCODE_SHIFT), 1.296 + 1.297 + LHZ_OPCODE = (40u << OPCODE_SHIFT), 1.298 + LHZX_OPCODE = (31u << OPCODE_SHIFT | 279u << 1), 1.299 + LHZU_OPCODE = (41u << OPCODE_SHIFT), 1.300 + 1.301 + LBZ_OPCODE = (34u << OPCODE_SHIFT), 1.302 + LBZX_OPCODE = (31u << OPCODE_SHIFT | 87u << 1), 1.303 + LBZU_OPCODE = (35u << OPCODE_SHIFT), 1.304 + 1.305 + STW_OPCODE = (36u << OPCODE_SHIFT), 1.306 + STWX_OPCODE = (31u << OPCODE_SHIFT | 151u << 1), 1.307 + STWU_OPCODE = (37u << OPCODE_SHIFT), 1.308 + STWUX_OPCODE = (31u << OPCODE_SHIFT | 183u << 1), 1.309 + 1.310 + STH_OPCODE = (44u << OPCODE_SHIFT), 1.311 + STHX_OPCODE = (31u << OPCODE_SHIFT | 407u << 1), 1.312 + STHU_OPCODE = (45u << OPCODE_SHIFT), 1.313 + 1.314 + STB_OPCODE = (38u << OPCODE_SHIFT), 1.315 + STBX_OPCODE = (31u << OPCODE_SHIFT | 215u << 1), 1.316 + STBU_OPCODE = (39u << OPCODE_SHIFT), 1.317 + 1.318 + EXTSB_OPCODE = (31u << OPCODE_SHIFT | 954u << 1), 1.319 + EXTSH_OPCODE = (31u << OPCODE_SHIFT | 922u << 1), 1.320 + EXTSW_OPCODE = (31u << OPCODE_SHIFT | 986u << 1), // X-FORM 1.321 + 1.322 + // 32 bit opcode encodings 1.323 + 1.324 + LWA_OPCODE = (58u << OPCODE_SHIFT | 2u << XO_30_31_SHIFT), // DS-FORM 1.325 + LWAX_OPCODE = (31u << OPCODE_SHIFT | 341u << XO_21_30_SHIFT), // X-FORM 1.326 + 1.327 + CNTLZW_OPCODE = (31u << OPCODE_SHIFT | 26u << XO_21_30_SHIFT), // X-FORM 1.328 + 1.329 + // 64 bit opcode encodings 1.330 + 1.331 + LD_OPCODE = (58u << OPCODE_SHIFT | 0u << XO_30_31_SHIFT), // DS-FORM 1.332 + LDU_OPCODE = (58u << OPCODE_SHIFT | 1u << XO_30_31_SHIFT), // DS-FORM 1.333 + LDX_OPCODE = (31u << OPCODE_SHIFT | 21u << XO_21_30_SHIFT), // X-FORM 1.334 + 1.335 + STD_OPCODE = (62u << OPCODE_SHIFT | 0u << XO_30_31_SHIFT), // DS-FORM 1.336 + STDU_OPCODE = (62u << OPCODE_SHIFT | 1u << XO_30_31_SHIFT), // DS-FORM 1.337 + STDUX_OPCODE = (31u << OPCODE_SHIFT | 181u << 1), // X-FORM 1.338 + STDX_OPCODE = (31u << OPCODE_SHIFT | 149u << XO_21_30_SHIFT), // X-FORM 1.339 + 1.340 + RLDICR_OPCODE = (30u << OPCODE_SHIFT | 1u << XO_27_29_SHIFT), // MD-FORM 1.341 + RLDICL_OPCODE = (30u << OPCODE_SHIFT | 0u << XO_27_29_SHIFT), // MD-FORM 1.342 + RLDIC_OPCODE = (30u << OPCODE_SHIFT | 2u << XO_27_29_SHIFT), // MD-FORM 1.343 + RLDIMI_OPCODE = (30u << OPCODE_SHIFT | 3u << XO_27_29_SHIFT), // MD-FORM 1.344 + 1.345 + SRADI_OPCODE = (31u << OPCODE_SHIFT | 413u << XO_21_29_SHIFT), // XS-FORM 1.346 + 1.347 + SLD_OPCODE = (31u << OPCODE_SHIFT | 27u << 1), // X-FORM 1.348 + SRD_OPCODE = (31u << OPCODE_SHIFT | 539u << 1), // X-FORM 1.349 + SRAD_OPCODE = (31u << OPCODE_SHIFT | 794u << 1), // X-FORM 1.350 + 1.351 + MULLD_OPCODE = (31u << OPCODE_SHIFT | 233u << 1), // XO-FORM 1.352 + MULHD_OPCODE = (31u << OPCODE_SHIFT | 73u << 1), // XO-FORM 1.353 + MULHDU_OPCODE = (31u << OPCODE_SHIFT | 9u << 1), // XO-FORM 1.354 + DIVD_OPCODE = (31u << OPCODE_SHIFT | 489u << 1), // XO-FORM 1.355 + 1.356 + CNTLZD_OPCODE = (31u << OPCODE_SHIFT | 58u << XO_21_30_SHIFT), // X-FORM 1.357 + NAND_OPCODE = (31u << OPCODE_SHIFT | 476u << XO_21_30_SHIFT), // X-FORM 1.358 + NOR_OPCODE = (31u << OPCODE_SHIFT | 124u << XO_21_30_SHIFT), // X-FORM 1.359 + 1.360 + 1.361 + // opcodes only used for floating arithmetic 1.362 + FADD_OPCODE = (63u << OPCODE_SHIFT | 21u << 1), 1.363 + FADDS_OPCODE = (59u << OPCODE_SHIFT | 21u << 1), 1.364 + FCMPU_OPCODE = (63u << OPCODE_SHIFT | 00u << 1), 1.365 + FDIV_OPCODE = (63u << OPCODE_SHIFT | 18u << 1), 1.366 + FDIVS_OPCODE = (59u << OPCODE_SHIFT | 18u << 1), 1.367 + FMR_OPCODE = (63u << OPCODE_SHIFT | 72u << 1), 1.368 + // These are special Power6 opcodes, reused for "lfdepx" and "stfdepx" 1.369 + // on Power7. Do not use. 1.370 + // MFFGPR_OPCODE = (31u << OPCODE_SHIFT | 607u << 1), 1.371 + // MFTGPR_OPCODE = (31u << OPCODE_SHIFT | 735u << 1), 1.372 + CMPB_OPCODE = (31u << OPCODE_SHIFT | 508 << 1), 1.373 + POPCNTB_OPCODE = (31u << OPCODE_SHIFT | 122 << 1), 1.374 + POPCNTW_OPCODE = (31u << OPCODE_SHIFT | 378 << 1), 1.375 + POPCNTD_OPCODE = (31u << OPCODE_SHIFT | 506 << 1), 1.376 + FABS_OPCODE = (63u << OPCODE_SHIFT | 264u << 1), 1.377 + FNABS_OPCODE = (63u << OPCODE_SHIFT | 136u << 1), 1.378 + FMUL_OPCODE = (63u << OPCODE_SHIFT | 25u << 1), 1.379 + FMULS_OPCODE = (59u << OPCODE_SHIFT | 25u << 1), 1.380 + FNEG_OPCODE = (63u << OPCODE_SHIFT | 40u << 1), 1.381 + FSUB_OPCODE = (63u << OPCODE_SHIFT | 20u << 1), 1.382 + FSUBS_OPCODE = (59u << OPCODE_SHIFT | 20u << 1), 1.383 + 1.384 + // PPC64-internal FPU conversion opcodes 1.385 + FCFID_OPCODE = (63u << OPCODE_SHIFT | 846u << 1), 1.386 + FCFIDS_OPCODE = (59u << OPCODE_SHIFT | 846u << 1), 1.387 + FCTID_OPCODE = (63u << OPCODE_SHIFT | 814u << 1), 1.388 + FCTIDZ_OPCODE = (63u << OPCODE_SHIFT | 815u << 1), 1.389 + FCTIW_OPCODE = (63u << OPCODE_SHIFT | 14u << 1), 1.390 + FCTIWZ_OPCODE = (63u << OPCODE_SHIFT | 15u << 1), 1.391 + FRSP_OPCODE = (63u << OPCODE_SHIFT | 12u << 1), 1.392 + 1.393 + // WARNING: using fmadd results in a non-compliant vm. Some floating 1.394 + // point tck tests will fail. 1.395 + FMADD_OPCODE = (59u << OPCODE_SHIFT | 29u << 1), 1.396 + DMADD_OPCODE = (63u << OPCODE_SHIFT | 29u << 1), 1.397 + FMSUB_OPCODE = (59u << OPCODE_SHIFT | 28u << 1), 1.398 + DMSUB_OPCODE = (63u << OPCODE_SHIFT | 28u << 1), 1.399 + FNMADD_OPCODE = (59u << OPCODE_SHIFT | 31u << 1), 1.400 + DNMADD_OPCODE = (63u << OPCODE_SHIFT | 31u << 1), 1.401 + FNMSUB_OPCODE = (59u << OPCODE_SHIFT | 30u << 1), 1.402 + DNMSUB_OPCODE = (63u << OPCODE_SHIFT | 30u << 1), 1.403 + 1.404 + LFD_OPCODE = (50u << OPCODE_SHIFT | 00u << 1), 1.405 + LFDU_OPCODE = (51u << OPCODE_SHIFT | 00u << 1), 1.406 + LFDX_OPCODE = (31u << OPCODE_SHIFT | 599u << 1), 1.407 + LFS_OPCODE = (48u << OPCODE_SHIFT | 00u << 1), 1.408 + LFSU_OPCODE = (49u << OPCODE_SHIFT | 00u << 1), 1.409 + LFSX_OPCODE = (31u << OPCODE_SHIFT | 535u << 1), 1.410 + 1.411 + STFD_OPCODE = (54u << OPCODE_SHIFT | 00u << 1), 1.412 + STFDU_OPCODE = (55u << OPCODE_SHIFT | 00u << 1), 1.413 + STFDX_OPCODE = (31u << OPCODE_SHIFT | 727u << 1), 1.414 + STFS_OPCODE = (52u << OPCODE_SHIFT | 00u << 1), 1.415 + STFSU_OPCODE = (53u << OPCODE_SHIFT | 00u << 1), 1.416 + STFSX_OPCODE = (31u << OPCODE_SHIFT | 663u << 1), 1.417 + 1.418 + FSQRT_OPCODE = (63u << OPCODE_SHIFT | 22u << 1), // A-FORM 1.419 + FSQRTS_OPCODE = (59u << OPCODE_SHIFT | 22u << 1), // A-FORM 1.420 + 1.421 + // Vector instruction support for >= Power6 1.422 + // Vector Storage Access 1.423 + LVEBX_OPCODE = (31u << OPCODE_SHIFT | 7u << 1), 1.424 + LVEHX_OPCODE = (31u << OPCODE_SHIFT | 39u << 1), 1.425 + LVEWX_OPCODE = (31u << OPCODE_SHIFT | 71u << 1), 1.426 + LVX_OPCODE = (31u << OPCODE_SHIFT | 103u << 1), 1.427 + LVXL_OPCODE = (31u << OPCODE_SHIFT | 359u << 1), 1.428 + STVEBX_OPCODE = (31u << OPCODE_SHIFT | 135u << 1), 1.429 + STVEHX_OPCODE = (31u << OPCODE_SHIFT | 167u << 1), 1.430 + STVEWX_OPCODE = (31u << OPCODE_SHIFT | 199u << 1), 1.431 + STVX_OPCODE = (31u << OPCODE_SHIFT | 231u << 1), 1.432 + STVXL_OPCODE = (31u << OPCODE_SHIFT | 487u << 1), 1.433 + LVSL_OPCODE = (31u << OPCODE_SHIFT | 6u << 1), 1.434 + LVSR_OPCODE = (31u << OPCODE_SHIFT | 38u << 1), 1.435 + 1.436 + // Vector Permute and Formatting 1.437 + VPKPX_OPCODE = (4u << OPCODE_SHIFT | 782u ), 1.438 + VPKSHSS_OPCODE = (4u << OPCODE_SHIFT | 398u ), 1.439 + VPKSWSS_OPCODE = (4u << OPCODE_SHIFT | 462u ), 1.440 + VPKSHUS_OPCODE = (4u << OPCODE_SHIFT | 270u ), 1.441 + VPKSWUS_OPCODE = (4u << OPCODE_SHIFT | 334u ), 1.442 + VPKUHUM_OPCODE = (4u << OPCODE_SHIFT | 14u ), 1.443 + VPKUWUM_OPCODE = (4u << OPCODE_SHIFT | 78u ), 1.444 + VPKUHUS_OPCODE = (4u << OPCODE_SHIFT | 142u ), 1.445 + VPKUWUS_OPCODE = (4u << OPCODE_SHIFT | 206u ), 1.446 + VUPKHPX_OPCODE = (4u << OPCODE_SHIFT | 846u ), 1.447 + VUPKHSB_OPCODE = (4u << OPCODE_SHIFT | 526u ), 1.448 + VUPKHSH_OPCODE = (4u << OPCODE_SHIFT | 590u ), 1.449 + VUPKLPX_OPCODE = (4u << OPCODE_SHIFT | 974u ), 1.450 + VUPKLSB_OPCODE = (4u << OPCODE_SHIFT | 654u ), 1.451 + VUPKLSH_OPCODE = (4u << OPCODE_SHIFT | 718u ), 1.452 + 1.453 + VMRGHB_OPCODE = (4u << OPCODE_SHIFT | 12u ), 1.454 + VMRGHW_OPCODE = (4u << OPCODE_SHIFT | 140u ), 1.455 + VMRGHH_OPCODE = (4u << OPCODE_SHIFT | 76u ), 1.456 + VMRGLB_OPCODE = (4u << OPCODE_SHIFT | 268u ), 1.457 + VMRGLW_OPCODE = (4u << OPCODE_SHIFT | 396u ), 1.458 + VMRGLH_OPCODE = (4u << OPCODE_SHIFT | 332u ), 1.459 + 1.460 + VSPLT_OPCODE = (4u << OPCODE_SHIFT | 524u ), 1.461 + VSPLTH_OPCODE = (4u << OPCODE_SHIFT | 588u ), 1.462 + VSPLTW_OPCODE = (4u << OPCODE_SHIFT | 652u ), 1.463 + VSPLTISB_OPCODE= (4u << OPCODE_SHIFT | 780u ), 1.464 + VSPLTISH_OPCODE= (4u << OPCODE_SHIFT | 844u ), 1.465 + VSPLTISW_OPCODE= (4u << OPCODE_SHIFT | 908u ), 1.466 + 1.467 + VPERM_OPCODE = (4u << OPCODE_SHIFT | 43u ), 1.468 + VSEL_OPCODE = (4u << OPCODE_SHIFT | 42u ), 1.469 + 1.470 + VSL_OPCODE = (4u << OPCODE_SHIFT | 452u ), 1.471 + VSLDOI_OPCODE = (4u << OPCODE_SHIFT | 44u ), 1.472 + VSLO_OPCODE = (4u << OPCODE_SHIFT | 1036u ), 1.473 + VSR_OPCODE = (4u << OPCODE_SHIFT | 708u ), 1.474 + VSRO_OPCODE = (4u << OPCODE_SHIFT | 1100u ), 1.475 + 1.476 + // Vector Integer 1.477 + VADDCUW_OPCODE = (4u << OPCODE_SHIFT | 384u ), 1.478 + VADDSHS_OPCODE = (4u << OPCODE_SHIFT | 832u ), 1.479 + VADDSBS_OPCODE = (4u << OPCODE_SHIFT | 768u ), 1.480 + VADDSWS_OPCODE = (4u << OPCODE_SHIFT | 896u ), 1.481 + VADDUBM_OPCODE = (4u << OPCODE_SHIFT | 0u ), 1.482 + VADDUWM_OPCODE = (4u << OPCODE_SHIFT | 128u ), 1.483 + VADDUHM_OPCODE = (4u << OPCODE_SHIFT | 64u ), 1.484 + VADDUBS_OPCODE = (4u << OPCODE_SHIFT | 512u ), 1.485 + VADDUWS_OPCODE = (4u << OPCODE_SHIFT | 640u ), 1.486 + VADDUHS_OPCODE = (4u << OPCODE_SHIFT | 576u ), 1.487 + VSUBCUW_OPCODE = (4u << OPCODE_SHIFT | 1408u ), 1.488 + VSUBSHS_OPCODE = (4u << OPCODE_SHIFT | 1856u ), 1.489 + VSUBSBS_OPCODE = (4u << OPCODE_SHIFT | 1792u ), 1.490 + VSUBSWS_OPCODE = (4u << OPCODE_SHIFT | 1920u ), 1.491 + VSUBUBM_OPCODE = (4u << OPCODE_SHIFT | 1024u ), 1.492 + VSUBUWM_OPCODE = (4u << OPCODE_SHIFT | 1152u ), 1.493 + VSUBUHM_OPCODE = (4u << OPCODE_SHIFT | 1088u ), 1.494 + VSUBUBS_OPCODE = (4u << OPCODE_SHIFT | 1536u ), 1.495 + VSUBUWS_OPCODE = (4u << OPCODE_SHIFT | 1664u ), 1.496 + VSUBUHS_OPCODE = (4u << OPCODE_SHIFT | 1600u ), 1.497 + 1.498 + VMULESB_OPCODE = (4u << OPCODE_SHIFT | 776u ), 1.499 + VMULEUB_OPCODE = (4u << OPCODE_SHIFT | 520u ), 1.500 + VMULESH_OPCODE = (4u << OPCODE_SHIFT | 840u ), 1.501 + VMULEUH_OPCODE = (4u << OPCODE_SHIFT | 584u ), 1.502 + VMULOSB_OPCODE = (4u << OPCODE_SHIFT | 264u ), 1.503 + VMULOUB_OPCODE = (4u << OPCODE_SHIFT | 8u ), 1.504 + VMULOSH_OPCODE = (4u << OPCODE_SHIFT | 328u ), 1.505 + VMULOUH_OPCODE = (4u << OPCODE_SHIFT | 72u ), 1.506 + VMHADDSHS_OPCODE=(4u << OPCODE_SHIFT | 32u ), 1.507 + VMHRADDSHS_OPCODE=(4u << OPCODE_SHIFT | 33u ), 1.508 + VMLADDUHM_OPCODE=(4u << OPCODE_SHIFT | 34u ), 1.509 + VMSUBUHM_OPCODE= (4u << OPCODE_SHIFT | 36u ), 1.510 + VMSUMMBM_OPCODE= (4u << OPCODE_SHIFT | 37u ), 1.511 + VMSUMSHM_OPCODE= (4u << OPCODE_SHIFT | 40u ), 1.512 + VMSUMSHS_OPCODE= (4u << OPCODE_SHIFT | 41u ), 1.513 + VMSUMUHM_OPCODE= (4u << OPCODE_SHIFT | 38u ), 1.514 + VMSUMUHS_OPCODE= (4u << OPCODE_SHIFT | 39u ), 1.515 + 1.516 + VSUMSWS_OPCODE = (4u << OPCODE_SHIFT | 1928u ), 1.517 + VSUM2SWS_OPCODE= (4u << OPCODE_SHIFT | 1672u ), 1.518 + VSUM4SBS_OPCODE= (4u << OPCODE_SHIFT | 1800u ), 1.519 + VSUM4UBS_OPCODE= (4u << OPCODE_SHIFT | 1544u ), 1.520 + VSUM4SHS_OPCODE= (4u << OPCODE_SHIFT | 1608u ), 1.521 + 1.522 + VAVGSB_OPCODE = (4u << OPCODE_SHIFT | 1282u ), 1.523 + VAVGSW_OPCODE = (4u << OPCODE_SHIFT | 1410u ), 1.524 + VAVGSH_OPCODE = (4u << OPCODE_SHIFT | 1346u ), 1.525 + VAVGUB_OPCODE = (4u << OPCODE_SHIFT | 1026u ), 1.526 + VAVGUW_OPCODE = (4u << OPCODE_SHIFT | 1154u ), 1.527 + VAVGUH_OPCODE = (4u << OPCODE_SHIFT | 1090u ), 1.528 + 1.529 + VMAXSB_OPCODE = (4u << OPCODE_SHIFT | 258u ), 1.530 + VMAXSW_OPCODE = (4u << OPCODE_SHIFT | 386u ), 1.531 + VMAXSH_OPCODE = (4u << OPCODE_SHIFT | 322u ), 1.532 + VMAXUB_OPCODE = (4u << OPCODE_SHIFT | 2u ), 1.533 + VMAXUW_OPCODE = (4u << OPCODE_SHIFT | 130u ), 1.534 + VMAXUH_OPCODE = (4u << OPCODE_SHIFT | 66u ), 1.535 + VMINSB_OPCODE = (4u << OPCODE_SHIFT | 770u ), 1.536 + VMINSW_OPCODE = (4u << OPCODE_SHIFT | 898u ), 1.537 + VMINSH_OPCODE = (4u << OPCODE_SHIFT | 834u ), 1.538 + VMINUB_OPCODE = (4u << OPCODE_SHIFT | 514u ), 1.539 + VMINUW_OPCODE = (4u << OPCODE_SHIFT | 642u ), 1.540 + VMINUH_OPCODE = (4u << OPCODE_SHIFT | 578u ), 1.541 + 1.542 + VCMPEQUB_OPCODE= (4u << OPCODE_SHIFT | 6u ), 1.543 + VCMPEQUH_OPCODE= (4u << OPCODE_SHIFT | 70u ), 1.544 + VCMPEQUW_OPCODE= (4u << OPCODE_SHIFT | 134u ), 1.545 + VCMPGTSH_OPCODE= (4u << OPCODE_SHIFT | 838u ), 1.546 + VCMPGTSB_OPCODE= (4u << OPCODE_SHIFT | 774u ), 1.547 + VCMPGTSW_OPCODE= (4u << OPCODE_SHIFT | 902u ), 1.548 + VCMPGTUB_OPCODE= (4u << OPCODE_SHIFT | 518u ), 1.549 + VCMPGTUH_OPCODE= (4u << OPCODE_SHIFT | 582u ), 1.550 + VCMPGTUW_OPCODE= (4u << OPCODE_SHIFT | 646u ), 1.551 + 1.552 + VAND_OPCODE = (4u << OPCODE_SHIFT | 1028u ), 1.553 + VANDC_OPCODE = (4u << OPCODE_SHIFT | 1092u ), 1.554 + VNOR_OPCODE = (4u << OPCODE_SHIFT | 1284u ), 1.555 + VOR_OPCODE = (4u << OPCODE_SHIFT | 1156u ), 1.556 + VXOR_OPCODE = (4u << OPCODE_SHIFT | 1220u ), 1.557 + VRLB_OPCODE = (4u << OPCODE_SHIFT | 4u ), 1.558 + VRLW_OPCODE = (4u << OPCODE_SHIFT | 132u ), 1.559 + VRLH_OPCODE = (4u << OPCODE_SHIFT | 68u ), 1.560 + VSLB_OPCODE = (4u << OPCODE_SHIFT | 260u ), 1.561 + VSKW_OPCODE = (4u << OPCODE_SHIFT | 388u ), 1.562 + VSLH_OPCODE = (4u << OPCODE_SHIFT | 324u ), 1.563 + VSRB_OPCODE = (4u << OPCODE_SHIFT | 516u ), 1.564 + VSRW_OPCODE = (4u << OPCODE_SHIFT | 644u ), 1.565 + VSRH_OPCODE = (4u << OPCODE_SHIFT | 580u ), 1.566 + VSRAB_OPCODE = (4u << OPCODE_SHIFT | 772u ), 1.567 + VSRAW_OPCODE = (4u << OPCODE_SHIFT | 900u ), 1.568 + VSRAH_OPCODE = (4u << OPCODE_SHIFT | 836u ), 1.569 + 1.570 + // Vector Floating-Point 1.571 + // not implemented yet 1.572 + 1.573 + // Vector Status and Control 1.574 + MTVSCR_OPCODE = (4u << OPCODE_SHIFT | 1604u ), 1.575 + MFVSCR_OPCODE = (4u << OPCODE_SHIFT | 1540u ), 1.576 + 1.577 + // Icache and dcache related instructions 1.578 + DCBA_OPCODE = (31u << OPCODE_SHIFT | 758u << 1), 1.579 + DCBZ_OPCODE = (31u << OPCODE_SHIFT | 1014u << 1), 1.580 + DCBST_OPCODE = (31u << OPCODE_SHIFT | 54u << 1), 1.581 + DCBF_OPCODE = (31u << OPCODE_SHIFT | 86u << 1), 1.582 + 1.583 + DCBT_OPCODE = (31u << OPCODE_SHIFT | 278u << 1), 1.584 + DCBTST_OPCODE = (31u << OPCODE_SHIFT | 246u << 1), 1.585 + ICBI_OPCODE = (31u << OPCODE_SHIFT | 982u << 1), 1.586 + 1.587 + // Instruction synchronization 1.588 + ISYNC_OPCODE = (19u << OPCODE_SHIFT | 150u << 1), 1.589 + // Memory barriers 1.590 + SYNC_OPCODE = (31u << OPCODE_SHIFT | 598u << 1), 1.591 + EIEIO_OPCODE = (31u << OPCODE_SHIFT | 854u << 1), 1.592 + 1.593 + // Trap instructions 1.594 + TDI_OPCODE = (2u << OPCODE_SHIFT), 1.595 + TWI_OPCODE = (3u << OPCODE_SHIFT), 1.596 + TD_OPCODE = (31u << OPCODE_SHIFT | 68u << 1), 1.597 + TW_OPCODE = (31u << OPCODE_SHIFT | 4u << 1), 1.598 + 1.599 + // Atomics. 1.600 + LWARX_OPCODE = (31u << OPCODE_SHIFT | 20u << 1), 1.601 + LDARX_OPCODE = (31u << OPCODE_SHIFT | 84u << 1), 1.602 + STWCX_OPCODE = (31u << OPCODE_SHIFT | 150u << 1), 1.603 + STDCX_OPCODE = (31u << OPCODE_SHIFT | 214u << 1) 1.604 + 1.605 + }; 1.606 + 1.607 + // Trap instructions TO bits 1.608 + enum trap_to_bits { 1.609 + // single bits 1.610 + traptoLessThanSigned = 1 << 4, // 0, left end 1.611 + traptoGreaterThanSigned = 1 << 3, 1.612 + traptoEqual = 1 << 2, 1.613 + traptoLessThanUnsigned = 1 << 1, 1.614 + traptoGreaterThanUnsigned = 1 << 0, // 4, right end 1.615 + 1.616 + // compound ones 1.617 + traptoUnconditional = (traptoLessThanSigned | 1.618 + traptoGreaterThanSigned | 1.619 + traptoEqual | 1.620 + traptoLessThanUnsigned | 1.621 + traptoGreaterThanUnsigned) 1.622 + }; 1.623 + 1.624 + // Branch hints BH field 1.625 + enum branch_hint_bh { 1.626 + // bclr cases: 1.627 + bhintbhBCLRisReturn = 0, 1.628 + bhintbhBCLRisNotReturnButSame = 1, 1.629 + bhintbhBCLRisNotPredictable = 3, 1.630 + 1.631 + // bcctr cases: 1.632 + bhintbhBCCTRisNotReturnButSame = 0, 1.633 + bhintbhBCCTRisNotPredictable = 3 1.634 + }; 1.635 + 1.636 + // Branch prediction hints AT field 1.637 + enum branch_hint_at { 1.638 + bhintatNoHint = 0, // at=00 1.639 + bhintatIsNotTaken = 2, // at=10 1.640 + bhintatIsTaken = 3 // at=11 1.641 + }; 1.642 + 1.643 + // Branch prediction hints 1.644 + enum branch_hint_concept { 1.645 + // Use the same encoding as branch_hint_at to simply code. 1.646 + bhintNoHint = bhintatNoHint, 1.647 + bhintIsNotTaken = bhintatIsNotTaken, 1.648 + bhintIsTaken = bhintatIsTaken 1.649 + }; 1.650 + 1.651 + // Used in BO field of branch instruction. 1.652 + enum branch_condition { 1.653 + bcondCRbiIs0 = 4, // bo=001at 1.654 + bcondCRbiIs1 = 12, // bo=011at 1.655 + bcondAlways = 20 // bo=10100 1.656 + }; 1.657 + 1.658 + // Branch condition with combined prediction hints. 1.659 + enum branch_condition_with_hint { 1.660 + bcondCRbiIs0_bhintNoHint = bcondCRbiIs0 | bhintatNoHint, 1.661 + bcondCRbiIs0_bhintIsNotTaken = bcondCRbiIs0 | bhintatIsNotTaken, 1.662 + bcondCRbiIs0_bhintIsTaken = bcondCRbiIs0 | bhintatIsTaken, 1.663 + bcondCRbiIs1_bhintNoHint = bcondCRbiIs1 | bhintatNoHint, 1.664 + bcondCRbiIs1_bhintIsNotTaken = bcondCRbiIs1 | bhintatIsNotTaken, 1.665 + bcondCRbiIs1_bhintIsTaken = bcondCRbiIs1 | bhintatIsTaken, 1.666 + }; 1.667 + 1.668 + // Branch prediction hints. 1.669 + inline static int add_bhint_to_boint(const int bhint, const int boint) { 1.670 + switch (boint) { 1.671 + case bcondCRbiIs0: 1.672 + case bcondCRbiIs1: 1.673 + // branch_hint and branch_hint_at have same encodings 1.674 + assert( (int)bhintNoHint == (int)bhintatNoHint 1.675 + && (int)bhintIsNotTaken == (int)bhintatIsNotTaken 1.676 + && (int)bhintIsTaken == (int)bhintatIsTaken, 1.677 + "wrong encodings"); 1.678 + assert((bhint & 0x03) == bhint, "wrong encodings"); 1.679 + return (boint & ~0x03) | bhint; 1.680 + case bcondAlways: 1.681 + // no branch_hint 1.682 + return boint; 1.683 + default: 1.684 + ShouldNotReachHere(); 1.685 + return 0; 1.686 + } 1.687 + } 1.688 + 1.689 + // Extract bcond from boint. 1.690 + inline static int inv_boint_bcond(const int boint) { 1.691 + int r_bcond = boint & ~0x03; 1.692 + assert(r_bcond == bcondCRbiIs0 || 1.693 + r_bcond == bcondCRbiIs1 || 1.694 + r_bcond == bcondAlways, 1.695 + "bad branch condition"); 1.696 + return r_bcond; 1.697 + } 1.698 + 1.699 + // Extract bhint from boint. 1.700 + inline static int inv_boint_bhint(const int boint) { 1.701 + int r_bhint = boint & 0x03; 1.702 + assert(r_bhint == bhintatNoHint || 1.703 + r_bhint == bhintatIsNotTaken || 1.704 + r_bhint == bhintatIsTaken, 1.705 + "bad branch hint"); 1.706 + return r_bhint; 1.707 + } 1.708 + 1.709 + // Calculate opposite of given bcond. 1.710 + inline static int opposite_bcond(const int bcond) { 1.711 + switch (bcond) { 1.712 + case bcondCRbiIs0: 1.713 + return bcondCRbiIs1; 1.714 + case bcondCRbiIs1: 1.715 + return bcondCRbiIs0; 1.716 + default: 1.717 + ShouldNotReachHere(); 1.718 + return 0; 1.719 + } 1.720 + } 1.721 + 1.722 + // Calculate opposite of given bhint. 1.723 + inline static int opposite_bhint(const int bhint) { 1.724 + switch (bhint) { 1.725 + case bhintatNoHint: 1.726 + return bhintatNoHint; 1.727 + case bhintatIsNotTaken: 1.728 + return bhintatIsTaken; 1.729 + case bhintatIsTaken: 1.730 + return bhintatIsNotTaken; 1.731 + default: 1.732 + ShouldNotReachHere(); 1.733 + return 0; 1.734 + } 1.735 + } 1.736 + 1.737 + // PPC branch instructions 1.738 + enum ppcops { 1.739 + b_op = 18, 1.740 + bc_op = 16, 1.741 + bcr_op = 19 1.742 + }; 1.743 + 1.744 + enum Condition { 1.745 + negative = 0, 1.746 + less = 0, 1.747 + positive = 1, 1.748 + greater = 1, 1.749 + zero = 2, 1.750 + equal = 2, 1.751 + summary_overflow = 3, 1.752 + }; 1.753 + 1.754 + public: 1.755 + // Helper functions for groups of instructions 1.756 + 1.757 + enum Predict { pt = 1, pn = 0 }; // pt = predict taken 1.758 + 1.759 + enum Membar_mask_bits { // page 184, v9 1.760 + StoreStore = 1 << 3, 1.761 + LoadStore = 1 << 2, 1.762 + StoreLoad = 1 << 1, 1.763 + LoadLoad = 1 << 0, 1.764 + 1.765 + Sync = 1 << 6, 1.766 + MemIssue = 1 << 5, 1.767 + Lookaside = 1 << 4 1.768 + }; 1.769 + 1.770 + // instruction must start at passed address 1.771 + static int instr_len(unsigned char *instr) { return BytesPerInstWord; } 1.772 + 1.773 + // instruction must be left-justified in argument 1.774 + static int instr_len(unsigned long instr) { return BytesPerInstWord; } 1.775 + 1.776 + // longest instructions 1.777 + static int instr_maxlen() { return BytesPerInstWord; } 1.778 + 1.779 + // Test if x is within signed immediate range for nbits. 1.780 + static bool is_simm(int x, unsigned int nbits) { 1.781 + assert(0 < nbits && nbits < 32, "out of bounds"); 1.782 + const int min = -( ((int)1) << nbits-1 ); 1.783 + const int maxplus1 = ( ((int)1) << nbits-1 ); 1.784 + return min <= x && x < maxplus1; 1.785 + } 1.786 + 1.787 + static bool is_simm(jlong x, unsigned int nbits) { 1.788 + assert(0 < nbits && nbits < 64, "out of bounds"); 1.789 + const jlong min = -( ((jlong)1) << nbits-1 ); 1.790 + const jlong maxplus1 = ( ((jlong)1) << nbits-1 ); 1.791 + return min <= x && x < maxplus1; 1.792 + } 1.793 + 1.794 + // Test if x is within unsigned immediate range for nbits 1.795 + static bool is_uimm(int x, unsigned int nbits) { 1.796 + assert(0 < nbits && nbits < 32, "out of bounds"); 1.797 + const int maxplus1 = ( ((int)1) << nbits ); 1.798 + return 0 <= x && x < maxplus1; 1.799 + } 1.800 + 1.801 + static bool is_uimm(jlong x, unsigned int nbits) { 1.802 + assert(0 < nbits && nbits < 64, "out of bounds"); 1.803 + const jlong maxplus1 = ( ((jlong)1) << nbits ); 1.804 + return 0 <= x && x < maxplus1; 1.805 + } 1.806 + 1.807 + protected: 1.808 + // helpers 1.809 + 1.810 + // X is supposed to fit in a field "nbits" wide 1.811 + // and be sign-extended. Check the range. 1.812 + static void assert_signed_range(intptr_t x, int nbits) { 1.813 + assert(nbits == 32 || (-(1 << nbits-1) <= x && x < (1 << nbits-1)), 1.814 + "value out of range"); 1.815 + } 1.816 + 1.817 + static void assert_signed_word_disp_range(intptr_t x, int nbits) { 1.818 + assert((x & 3) == 0, "not word aligned"); 1.819 + assert_signed_range(x, nbits + 2); 1.820 + } 1.821 + 1.822 + static void assert_unsigned_const(int x, int nbits) { 1.823 + assert(juint(x) < juint(1 << nbits), "unsigned constant out of range"); 1.824 + } 1.825 + 1.826 + static int fmask(juint hi_bit, juint lo_bit) { 1.827 + assert(hi_bit >= lo_bit && hi_bit < 32, "bad bits"); 1.828 + return (1 << ( hi_bit-lo_bit + 1 )) - 1; 1.829 + } 1.830 + 1.831 + // inverse of u_field 1.832 + static int inv_u_field(int x, int hi_bit, int lo_bit) { 1.833 + juint r = juint(x) >> lo_bit; 1.834 + r &= fmask(hi_bit, lo_bit); 1.835 + return int(r); 1.836 + } 1.837 + 1.838 + // signed version: extract from field and sign-extend 1.839 + static int inv_s_field_ppc(int x, int hi_bit, int lo_bit) { 1.840 + x = x << (31-hi_bit); 1.841 + x = x >> (31-hi_bit+lo_bit); 1.842 + return x; 1.843 + } 1.844 + 1.845 + static int u_field(int x, int hi_bit, int lo_bit) { 1.846 + assert((x & ~fmask(hi_bit, lo_bit)) == 0, "value out of range"); 1.847 + int r = x << lo_bit; 1.848 + assert(inv_u_field(r, hi_bit, lo_bit) == x, "just checking"); 1.849 + return r; 1.850 + } 1.851 + 1.852 + // Same as u_field for signed values 1.853 + static int s_field(int x, int hi_bit, int lo_bit) { 1.854 + int nbits = hi_bit - lo_bit + 1; 1.855 + assert(nbits == 32 || (-(1 << nbits-1) <= x && x < (1 << nbits-1)), 1.856 + "value out of range"); 1.857 + x &= fmask(hi_bit, lo_bit); 1.858 + int r = x << lo_bit; 1.859 + return r; 1.860 + } 1.861 + 1.862 + // inv_op for ppc instructions 1.863 + static int inv_op_ppc(int x) { return inv_u_field(x, 31, 26); } 1.864 + 1.865 + // Determine target address from li, bd field of branch instruction. 1.866 + static intptr_t inv_li_field(int x) { 1.867 + intptr_t r = inv_s_field_ppc(x, 25, 2); 1.868 + r = (r << 2); 1.869 + return r; 1.870 + } 1.871 + static intptr_t inv_bd_field(int x, intptr_t pos) { 1.872 + intptr_t r = inv_s_field_ppc(x, 15, 2); 1.873 + r = (r << 2) + pos; 1.874 + return r; 1.875 + } 1.876 + 1.877 + #define inv_opp_u_field(x, hi_bit, lo_bit) inv_u_field(x, 31-(lo_bit), 31-(hi_bit)) 1.878 + #define inv_opp_s_field(x, hi_bit, lo_bit) inv_s_field_ppc(x, 31-(lo_bit), 31-(hi_bit)) 1.879 + // Extract instruction fields from instruction words. 1.880 + public: 1.881 + static int inv_ra_field(int x) { return inv_opp_u_field(x, 15, 11); } 1.882 + static int inv_rb_field(int x) { return inv_opp_u_field(x, 20, 16); } 1.883 + static int inv_rt_field(int x) { return inv_opp_u_field(x, 10, 6); } 1.884 + static int inv_rs_field(int x) { return inv_opp_u_field(x, 10, 6); } 1.885 + // Ds uses opp_s_field(x, 31, 16), but lowest 2 bits must be 0. 1.886 + // Inv_ds_field uses range (x, 29, 16) but shifts by 2 to ensure that lowest bits are 0. 1.887 + static int inv_ds_field(int x) { return inv_opp_s_field(x, 29, 16) << 2; } 1.888 + static int inv_d1_field(int x) { return inv_opp_s_field(x, 31, 16); } 1.889 + static int inv_si_field(int x) { return inv_opp_s_field(x, 31, 16); } 1.890 + static int inv_to_field(int x) { return inv_opp_u_field(x, 10, 6); } 1.891 + static int inv_lk_field(int x) { return inv_opp_u_field(x, 31, 31); } 1.892 + static int inv_bo_field(int x) { return inv_opp_u_field(x, 10, 6); } 1.893 + static int inv_bi_field(int x) { return inv_opp_u_field(x, 15, 11); } 1.894 + 1.895 + #define opp_u_field(x, hi_bit, lo_bit) u_field(x, 31-(lo_bit), 31-(hi_bit)) 1.896 + #define opp_s_field(x, hi_bit, lo_bit) s_field(x, 31-(lo_bit), 31-(hi_bit)) 1.897 + 1.898 + // instruction fields 1.899 + static int aa( int x) { return opp_u_field(x, 30, 30); } 1.900 + static int ba( int x) { return opp_u_field(x, 15, 11); } 1.901 + static int bb( int x) { return opp_u_field(x, 20, 16); } 1.902 + static int bc( int x) { return opp_u_field(x, 25, 21); } 1.903 + static int bd( int x) { return opp_s_field(x, 29, 16); } 1.904 + static int bf( ConditionRegister cr) { return bf(cr->encoding()); } 1.905 + static int bf( int x) { return opp_u_field(x, 8, 6); } 1.906 + static int bfa(ConditionRegister cr) { return bfa(cr->encoding()); } 1.907 + static int bfa( int x) { return opp_u_field(x, 13, 11); } 1.908 + static int bh( int x) { return opp_u_field(x, 20, 19); } 1.909 + static int bi( int x) { return opp_u_field(x, 15, 11); } 1.910 + static int bi0(ConditionRegister cr, Condition c) { return (cr->encoding() << 2) | c; } 1.911 + static int bo( int x) { return opp_u_field(x, 10, 6); } 1.912 + static int bt( int x) { return opp_u_field(x, 10, 6); } 1.913 + static int d1( int x) { return opp_s_field(x, 31, 16); } 1.914 + static int ds( int x) { assert((x & 0x3) == 0, "unaligned offset"); return opp_s_field(x, 31, 16); } 1.915 + static int eh( int x) { return opp_u_field(x, 31, 31); } 1.916 + static int flm( int x) { return opp_u_field(x, 14, 7); } 1.917 + static int fra( FloatRegister r) { return fra(r->encoding());} 1.918 + static int frb( FloatRegister r) { return frb(r->encoding());} 1.919 + static int frc( FloatRegister r) { return frc(r->encoding());} 1.920 + static int frs( FloatRegister r) { return frs(r->encoding());} 1.921 + static int frt( FloatRegister r) { return frt(r->encoding());} 1.922 + static int fra( int x) { return opp_u_field(x, 15, 11); } 1.923 + static int frb( int x) { return opp_u_field(x, 20, 16); } 1.924 + static int frc( int x) { return opp_u_field(x, 25, 21); } 1.925 + static int frs( int x) { return opp_u_field(x, 10, 6); } 1.926 + static int frt( int x) { return opp_u_field(x, 10, 6); } 1.927 + static int fxm( int x) { return opp_u_field(x, 19, 12); } 1.928 + static int l10( int x) { return opp_u_field(x, 10, 10); } 1.929 + static int l15( int x) { return opp_u_field(x, 15, 15); } 1.930 + static int l910( int x) { return opp_u_field(x, 10, 9); } 1.931 + static int lev( int x) { return opp_u_field(x, 26, 20); } 1.932 + static int li( int x) { return opp_s_field(x, 29, 6); } 1.933 + static int lk( int x) { return opp_u_field(x, 31, 31); } 1.934 + static int mb2125( int x) { return opp_u_field(x, 25, 21); } 1.935 + static int me2630( int x) { return opp_u_field(x, 30, 26); } 1.936 + static int mb2126( int x) { return opp_u_field(((x & 0x1f) << 1) | ((x & 0x20) >> 5), 26, 21); } 1.937 + static int me2126( int x) { return mb2126(x); } 1.938 + static int nb( int x) { return opp_u_field(x, 20, 16); } 1.939 + //static int opcd( int x) { return opp_u_field(x, 5, 0); } // is contained in our opcodes 1.940 + static int oe( int x) { return opp_u_field(x, 21, 21); } 1.941 + static int ra( Register r) { return ra(r->encoding()); } 1.942 + static int ra( int x) { return opp_u_field(x, 15, 11); } 1.943 + static int rb( Register r) { return rb(r->encoding()); } 1.944 + static int rb( int x) { return opp_u_field(x, 20, 16); } 1.945 + static int rc( int x) { return opp_u_field(x, 31, 31); } 1.946 + static int rs( Register r) { return rs(r->encoding()); } 1.947 + static int rs( int x) { return opp_u_field(x, 10, 6); } 1.948 + // we don't want to use R0 in memory accesses, because it has value `0' then 1.949 + static int ra0mem( Register r) { assert(r != R0, "cannot use register R0 in memory access"); return ra(r); } 1.950 + static int ra0mem( int x) { assert(x != 0, "cannot use register 0 in memory access"); return ra(x); } 1.951 + 1.952 + // register r is target 1.953 + static int rt( Register r) { return rs(r); } 1.954 + static int rt( int x) { return rs(x); } 1.955 + static int rta( Register r) { return ra(r); } 1.956 + static int rta0mem( Register r) { rta(r); return ra0mem(r); } 1.957 + 1.958 + static int sh1620( int x) { return opp_u_field(x, 20, 16); } 1.959 + static int sh30( int x) { return opp_u_field(x, 30, 30); } 1.960 + static int sh162030( int x) { return sh1620(x & 0x1f) | sh30((x & 0x20) >> 5); } 1.961 + static int si( int x) { return opp_s_field(x, 31, 16); } 1.962 + static int spr( int x) { return opp_u_field(x, 20, 11); } 1.963 + static int sr( int x) { return opp_u_field(x, 15, 12); } 1.964 + static int tbr( int x) { return opp_u_field(x, 20, 11); } 1.965 + static int th( int x) { return opp_u_field(x, 10, 7); } 1.966 + static int thct( int x) { assert((x&8)==0, "must be valid cache specification"); return th(x); } 1.967 + static int thds( int x) { assert((x&8)==8, "must be valid stream specification"); return th(x); } 1.968 + static int to( int x) { return opp_u_field(x, 10, 6); } 1.969 + static int u( int x) { return opp_u_field(x, 19, 16); } 1.970 + static int ui( int x) { return opp_u_field(x, 31, 16); } 1.971 + 1.972 + // support vector instructions for >= Power6 1.973 + static int vra( int x) { return opp_u_field(x, 15, 11); } 1.974 + static int vrb( int x) { return opp_u_field(x, 20, 16); } 1.975 + static int vrc( int x) { return opp_u_field(x, 25, 21); } 1.976 + static int vrs( int x) { return opp_u_field(x, 10, 6); } 1.977 + static int vrt( int x) { return opp_u_field(x, 10, 6); } 1.978 + 1.979 + static int vra( VectorRegister r) { return vra(r->encoding());} 1.980 + static int vrb( VectorRegister r) { return vrb(r->encoding());} 1.981 + static int vrc( VectorRegister r) { return vrc(r->encoding());} 1.982 + static int vrs( VectorRegister r) { return vrs(r->encoding());} 1.983 + static int vrt( VectorRegister r) { return vrt(r->encoding());} 1.984 + 1.985 + static int vsplt_uim( int x) { return opp_u_field(x, 15, 12); } // for vsplt* instructions 1.986 + static int vsplti_sim(int x) { return opp_u_field(x, 15, 11); } // for vsplti* instructions 1.987 + static int vsldoi_shb(int x) { return opp_u_field(x, 25, 22); } // for vsldoi instruction 1.988 + static int vcmp_rc( int x) { return opp_u_field(x, 21, 21); } // for vcmp* instructions 1.989 + 1.990 + //static int xo1( int x) { return opp_u_field(x, 29, 21); }// is contained in our opcodes 1.991 + //static int xo2( int x) { return opp_u_field(x, 30, 21); }// is contained in our opcodes 1.992 + //static int xo3( int x) { return opp_u_field(x, 30, 22); }// is contained in our opcodes 1.993 + //static int xo4( int x) { return opp_u_field(x, 30, 26); }// is contained in our opcodes 1.994 + //static int xo5( int x) { return opp_u_field(x, 29, 27); }// is contained in our opcodes 1.995 + //static int xo6( int x) { return opp_u_field(x, 30, 27); }// is contained in our opcodes 1.996 + //static int xo7( int x) { return opp_u_field(x, 31, 30); }// is contained in our opcodes 1.997 + 1.998 + protected: 1.999 + // Compute relative address for branch. 1.1000 + static intptr_t disp(intptr_t x, intptr_t off) { 1.1001 + int xx = x - off; 1.1002 + xx = xx >> 2; 1.1003 + return xx; 1.1004 + } 1.1005 + 1.1006 + public: 1.1007 + // signed immediate, in low bits, nbits long 1.1008 + static int simm(int x, int nbits) { 1.1009 + assert_signed_range(x, nbits); 1.1010 + return x & ((1 << nbits) - 1); 1.1011 + } 1.1012 + 1.1013 + // unsigned immediate, in low bits, nbits long 1.1014 + static int uimm(int x, int nbits) { 1.1015 + assert_unsigned_const(x, nbits); 1.1016 + return x & ((1 << nbits) - 1); 1.1017 + } 1.1018 + 1.1019 + static void set_imm(int* instr, short s) { 1.1020 + short* p = ((short *)instr) + 1; 1.1021 + *p = s; 1.1022 + } 1.1023 + 1.1024 + static int get_imm(address a, int instruction_number) { 1.1025 + short imm; 1.1026 + short *p =((short *)a)+2*instruction_number+1; 1.1027 + imm = *p; 1.1028 + return (int)imm; 1.1029 + } 1.1030 + 1.1031 + static inline int hi16_signed( int x) { return (int)(int16_t)(x >> 16); } 1.1032 + static inline int lo16_unsigned(int x) { return x & 0xffff; } 1.1033 + 1.1034 + protected: 1.1035 + 1.1036 + // Extract the top 32 bits in a 64 bit word. 1.1037 + static int32_t hi32(int64_t x) { 1.1038 + int32_t r = int32_t((uint64_t)x >> 32); 1.1039 + return r; 1.1040 + } 1.1041 + 1.1042 + public: 1.1043 + 1.1044 + static inline unsigned int align_addr(unsigned int addr, unsigned int a) { 1.1045 + return ((addr + (a - 1)) & ~(a - 1)); 1.1046 + } 1.1047 + 1.1048 + static inline bool is_aligned(unsigned int addr, unsigned int a) { 1.1049 + return (0 == addr % a); 1.1050 + } 1.1051 + 1.1052 + void flush() { 1.1053 + AbstractAssembler::flush(); 1.1054 + } 1.1055 + 1.1056 + inline void emit_int32(int); // shadows AbstractAssembler::emit_int32 1.1057 + inline void emit_data(int); 1.1058 + inline void emit_data(int, RelocationHolder const&); 1.1059 + inline void emit_data(int, relocInfo::relocType rtype); 1.1060 + 1.1061 + // Emit an address. 1.1062 + inline address emit_addr(const address addr = NULL); 1.1063 + 1.1064 + // Emit a function descriptor with the specified entry point, TOC, 1.1065 + // and ENV. If the entry point is NULL, the descriptor will point 1.1066 + // just past the descriptor. 1.1067 + // Use values from friend functions as defaults. 1.1068 + inline address emit_fd(address entry = NULL, 1.1069 + address toc = (address) FunctionDescriptor::friend_toc, 1.1070 + address env = (address) FunctionDescriptor::friend_env); 1.1071 + 1.1072 + ///////////////////////////////////////////////////////////////////////////////////// 1.1073 + // PPC instructions 1.1074 + ///////////////////////////////////////////////////////////////////////////////////// 1.1075 + 1.1076 + // Memory instructions use r0 as hard coded 0, e.g. to simulate loading 1.1077 + // immediates. The normal instruction encoders enforce that r0 is not 1.1078 + // passed to them. Use either extended mnemonics encoders or the special ra0 1.1079 + // versions. 1.1080 + 1.1081 + // Issue an illegal instruction. 1.1082 + inline void illtrap(); 1.1083 + static inline bool is_illtrap(int x); 1.1084 + 1.1085 + // PPC 1, section 3.3.8, Fixed-Point Arithmetic Instructions 1.1086 + inline void addi( Register d, Register a, int si16); 1.1087 + inline void addis(Register d, Register a, int si16); 1.1088 + private: 1.1089 + inline void addi_r0ok( Register d, Register a, int si16); 1.1090 + inline void addis_r0ok(Register d, Register a, int si16); 1.1091 + public: 1.1092 + inline void addic_( Register d, Register a, int si16); 1.1093 + inline void subfic( Register d, Register a, int si16); 1.1094 + inline void add( Register d, Register a, Register b); 1.1095 + inline void add_( Register d, Register a, Register b); 1.1096 + inline void subf( Register d, Register a, Register b); 1.1097 + inline void sub( Register d, Register a, Register b); 1.1098 + inline void subf_( Register d, Register a, Register b); 1.1099 + inline void addc( Register d, Register a, Register b); 1.1100 + inline void addc_( Register d, Register a, Register b); 1.1101 + inline void subfc( Register d, Register a, Register b); 1.1102 + inline void subfc_( Register d, Register a, Register b); 1.1103 + inline void adde( Register d, Register a, Register b); 1.1104 + inline void adde_( Register d, Register a, Register b); 1.1105 + inline void subfe( Register d, Register a, Register b); 1.1106 + inline void subfe_( Register d, Register a, Register b); 1.1107 + inline void neg( Register d, Register a); 1.1108 + inline void neg_( Register d, Register a); 1.1109 + inline void mulli( Register d, Register a, int si16); 1.1110 + inline void mulld( Register d, Register a, Register b); 1.1111 + inline void mulld_( Register d, Register a, Register b); 1.1112 + inline void mullw( Register d, Register a, Register b); 1.1113 + inline void mullw_( Register d, Register a, Register b); 1.1114 + inline void mulhw( Register d, Register a, Register b); 1.1115 + inline void mulhw_( Register d, Register a, Register b); 1.1116 + inline void mulhd( Register d, Register a, Register b); 1.1117 + inline void mulhd_( Register d, Register a, Register b); 1.1118 + inline void mulhdu( Register d, Register a, Register b); 1.1119 + inline void mulhdu_(Register d, Register a, Register b); 1.1120 + inline void divd( Register d, Register a, Register b); 1.1121 + inline void divd_( Register d, Register a, Register b); 1.1122 + inline void divw( Register d, Register a, Register b); 1.1123 + inline void divw_( Register d, Register a, Register b); 1.1124 + 1.1125 + // extended mnemonics 1.1126 + inline void li( Register d, int si16); 1.1127 + inline void lis( Register d, int si16); 1.1128 + inline void addir(Register d, int si16, Register a); 1.1129 + 1.1130 + static bool is_addi(int x) { 1.1131 + return ADDI_OPCODE == (x & ADDI_OPCODE_MASK); 1.1132 + } 1.1133 + static bool is_addis(int x) { 1.1134 + return ADDIS_OPCODE == (x & ADDIS_OPCODE_MASK); 1.1135 + } 1.1136 + static bool is_bxx(int x) { 1.1137 + return BXX_OPCODE == (x & BXX_OPCODE_MASK); 1.1138 + } 1.1139 + static bool is_b(int x) { 1.1140 + return BXX_OPCODE == (x & BXX_OPCODE_MASK) && inv_lk_field(x) == 0; 1.1141 + } 1.1142 + static bool is_bl(int x) { 1.1143 + return BXX_OPCODE == (x & BXX_OPCODE_MASK) && inv_lk_field(x) == 1; 1.1144 + } 1.1145 + static bool is_bcxx(int x) { 1.1146 + return BCXX_OPCODE == (x & BCXX_OPCODE_MASK); 1.1147 + } 1.1148 + static bool is_bxx_or_bcxx(int x) { 1.1149 + return is_bxx(x) || is_bcxx(x); 1.1150 + } 1.1151 + static bool is_bctrl(int x) { 1.1152 + return x == 0x4e800421; 1.1153 + } 1.1154 + static bool is_bctr(int x) { 1.1155 + return x == 0x4e800420; 1.1156 + } 1.1157 + static bool is_bclr(int x) { 1.1158 + return BCLR_OPCODE == (x & XL_FORM_OPCODE_MASK); 1.1159 + } 1.1160 + static bool is_li(int x) { 1.1161 + return is_addi(x) && inv_ra_field(x)==0; 1.1162 + } 1.1163 + static bool is_lis(int x) { 1.1164 + return is_addis(x) && inv_ra_field(x)==0; 1.1165 + } 1.1166 + static bool is_mtctr(int x) { 1.1167 + return MTCTR_OPCODE == (x & MTCTR_OPCODE_MASK); 1.1168 + } 1.1169 + static bool is_ld(int x) { 1.1170 + return LD_OPCODE == (x & LD_OPCODE_MASK); 1.1171 + } 1.1172 + static bool is_std(int x) { 1.1173 + return STD_OPCODE == (x & STD_OPCODE_MASK); 1.1174 + } 1.1175 + static bool is_stdu(int x) { 1.1176 + return STDU_OPCODE == (x & STDU_OPCODE_MASK); 1.1177 + } 1.1178 + static bool is_stdx(int x) { 1.1179 + return STDX_OPCODE == (x & STDX_OPCODE_MASK); 1.1180 + } 1.1181 + static bool is_stdux(int x) { 1.1182 + return STDUX_OPCODE == (x & STDUX_OPCODE_MASK); 1.1183 + } 1.1184 + static bool is_stwx(int x) { 1.1185 + return STWX_OPCODE == (x & STWX_OPCODE_MASK); 1.1186 + } 1.1187 + static bool is_stwux(int x) { 1.1188 + return STWUX_OPCODE == (x & STWUX_OPCODE_MASK); 1.1189 + } 1.1190 + static bool is_stw(int x) { 1.1191 + return STW_OPCODE == (x & STW_OPCODE_MASK); 1.1192 + } 1.1193 + static bool is_stwu(int x) { 1.1194 + return STWU_OPCODE == (x & STWU_OPCODE_MASK); 1.1195 + } 1.1196 + static bool is_ori(int x) { 1.1197 + return ORI_OPCODE == (x & ORI_OPCODE_MASK); 1.1198 + }; 1.1199 + static bool is_oris(int x) { 1.1200 + return ORIS_OPCODE == (x & ORIS_OPCODE_MASK); 1.1201 + }; 1.1202 + static bool is_rldicr(int x) { 1.1203 + return (RLDICR_OPCODE == (x & RLDICR_OPCODE_MASK)); 1.1204 + }; 1.1205 + static bool is_nop(int x) { 1.1206 + return x == 0x60000000; 1.1207 + } 1.1208 + // endgroup opcode for Power6 1.1209 + static bool is_endgroup(int x) { 1.1210 + return is_ori(x) && inv_ra_field(x)==1 && inv_rs_field(x)==1 && inv_d1_field(x)==0; 1.1211 + } 1.1212 + 1.1213 + 1.1214 + private: 1.1215 + // PPC 1, section 3.3.9, Fixed-Point Compare Instructions 1.1216 + inline void cmpi( ConditionRegister bf, int l, Register a, int si16); 1.1217 + inline void cmp( ConditionRegister bf, int l, Register a, Register b); 1.1218 + inline void cmpli(ConditionRegister bf, int l, Register a, int ui16); 1.1219 + inline void cmpl( ConditionRegister bf, int l, Register a, Register b); 1.1220 + 1.1221 + public: 1.1222 + // extended mnemonics of Compare Instructions 1.1223 + inline void cmpwi( ConditionRegister crx, Register a, int si16); 1.1224 + inline void cmpdi( ConditionRegister crx, Register a, int si16); 1.1225 + inline void cmpw( ConditionRegister crx, Register a, Register b); 1.1226 + inline void cmpd( ConditionRegister crx, Register a, Register b); 1.1227 + inline void cmplwi(ConditionRegister crx, Register a, int ui16); 1.1228 + inline void cmpldi(ConditionRegister crx, Register a, int ui16); 1.1229 + inline void cmplw( ConditionRegister crx, Register a, Register b); 1.1230 + inline void cmpld( ConditionRegister crx, Register a, Register b); 1.1231 + 1.1232 + inline void isel( Register d, Register a, Register b, int bc); 1.1233 + 1.1234 + // PPC 1, section 3.3.11, Fixed-Point Logical Instructions 1.1235 + void andi( Register a, Register s, int ui16); // optimized version 1.1236 + inline void andi_( Register a, Register s, int ui16); 1.1237 + inline void andis_( Register a, Register s, int ui16); 1.1238 + inline void ori( Register a, Register s, int ui16); 1.1239 + inline void oris( Register a, Register s, int ui16); 1.1240 + inline void xori( Register a, Register s, int ui16); 1.1241 + inline void xoris( Register a, Register s, int ui16); 1.1242 + inline void andr( Register a, Register s, Register b); // suffixed by 'r' as 'and' is C++ keyword 1.1243 + inline void and_( Register a, Register s, Register b); 1.1244 + // Turn or0(rx,rx,rx) into a nop and avoid that we accidently emit a 1.1245 + // SMT-priority change instruction (see SMT instructions below). 1.1246 + inline void or_unchecked(Register a, Register s, Register b); 1.1247 + inline void orr( Register a, Register s, Register b); // suffixed by 'r' as 'or' is C++ keyword 1.1248 + inline void or_( Register a, Register s, Register b); 1.1249 + inline void xorr( Register a, Register s, Register b); // suffixed by 'r' as 'xor' is C++ keyword 1.1250 + inline void xor_( Register a, Register s, Register b); 1.1251 + inline void nand( Register a, Register s, Register b); 1.1252 + inline void nand_( Register a, Register s, Register b); 1.1253 + inline void nor( Register a, Register s, Register b); 1.1254 + inline void nor_( Register a, Register s, Register b); 1.1255 + inline void andc( Register a, Register s, Register b); 1.1256 + inline void andc_( Register a, Register s, Register b); 1.1257 + inline void orc( Register a, Register s, Register b); 1.1258 + inline void orc_( Register a, Register s, Register b); 1.1259 + inline void extsb( Register a, Register s); 1.1260 + inline void extsh( Register a, Register s); 1.1261 + inline void extsw( Register a, Register s); 1.1262 + 1.1263 + // extended mnemonics 1.1264 + inline void nop(); 1.1265 + // NOP for FP and BR units (different versions to allow them to be in one group) 1.1266 + inline void fpnop0(); 1.1267 + inline void fpnop1(); 1.1268 + inline void brnop0(); 1.1269 + inline void brnop1(); 1.1270 + inline void brnop2(); 1.1271 + 1.1272 + inline void mr( Register d, Register s); 1.1273 + inline void ori_opt( Register d, int ui16); 1.1274 + inline void oris_opt(Register d, int ui16); 1.1275 + 1.1276 + // endgroup opcode for Power6 1.1277 + inline void endgroup(); 1.1278 + 1.1279 + // count instructions 1.1280 + inline void cntlzw( Register a, Register s); 1.1281 + inline void cntlzw_( Register a, Register s); 1.1282 + inline void cntlzd( Register a, Register s); 1.1283 + inline void cntlzd_( Register a, Register s); 1.1284 + 1.1285 + // PPC 1, section 3.3.12, Fixed-Point Rotate and Shift Instructions 1.1286 + inline void sld( Register a, Register s, Register b); 1.1287 + inline void sld_( Register a, Register s, Register b); 1.1288 + inline void slw( Register a, Register s, Register b); 1.1289 + inline void slw_( Register a, Register s, Register b); 1.1290 + inline void srd( Register a, Register s, Register b); 1.1291 + inline void srd_( Register a, Register s, Register b); 1.1292 + inline void srw( Register a, Register s, Register b); 1.1293 + inline void srw_( Register a, Register s, Register b); 1.1294 + inline void srad( Register a, Register s, Register b); 1.1295 + inline void srad_( Register a, Register s, Register b); 1.1296 + inline void sraw( Register a, Register s, Register b); 1.1297 + inline void sraw_( Register a, Register s, Register b); 1.1298 + inline void sradi( Register a, Register s, int sh6); 1.1299 + inline void sradi_( Register a, Register s, int sh6); 1.1300 + inline void srawi( Register a, Register s, int sh5); 1.1301 + inline void srawi_( Register a, Register s, int sh5); 1.1302 + 1.1303 + // extended mnemonics for Shift Instructions 1.1304 + inline void sldi( Register a, Register s, int sh6); 1.1305 + inline void sldi_( Register a, Register s, int sh6); 1.1306 + inline void slwi( Register a, Register s, int sh5); 1.1307 + inline void slwi_( Register a, Register s, int sh5); 1.1308 + inline void srdi( Register a, Register s, int sh6); 1.1309 + inline void srdi_( Register a, Register s, int sh6); 1.1310 + inline void srwi( Register a, Register s, int sh5); 1.1311 + inline void srwi_( Register a, Register s, int sh5); 1.1312 + 1.1313 + inline void clrrdi( Register a, Register s, int ui6); 1.1314 + inline void clrrdi_( Register a, Register s, int ui6); 1.1315 + inline void clrldi( Register a, Register s, int ui6); 1.1316 + inline void clrldi_( Register a, Register s, int ui6); 1.1317 + inline void clrlsldi(Register a, Register s, int clrl6, int shl6); 1.1318 + inline void clrlsldi_(Register a, Register s, int clrl6, int shl6); 1.1319 + inline void extrdi( Register a, Register s, int n, int b); 1.1320 + // testbit with condition register 1.1321 + inline void testbitdi(ConditionRegister cr, Register a, Register s, int ui6); 1.1322 + 1.1323 + // rotate instructions 1.1324 + inline void rotldi( Register a, Register s, int n); 1.1325 + inline void rotrdi( Register a, Register s, int n); 1.1326 + inline void rotlwi( Register a, Register s, int n); 1.1327 + inline void rotrwi( Register a, Register s, int n); 1.1328 + 1.1329 + // Rotate Instructions 1.1330 + inline void rldic( Register a, Register s, int sh6, int mb6); 1.1331 + inline void rldic_( Register a, Register s, int sh6, int mb6); 1.1332 + inline void rldicr( Register a, Register s, int sh6, int mb6); 1.1333 + inline void rldicr_( Register a, Register s, int sh6, int mb6); 1.1334 + inline void rldicl( Register a, Register s, int sh6, int mb6); 1.1335 + inline void rldicl_( Register a, Register s, int sh6, int mb6); 1.1336 + inline void rlwinm( Register a, Register s, int sh5, int mb5, int me5); 1.1337 + inline void rlwinm_( Register a, Register s, int sh5, int mb5, int me5); 1.1338 + inline void rldimi( Register a, Register s, int sh6, int mb6); 1.1339 + inline void rldimi_( Register a, Register s, int sh6, int mb6); 1.1340 + inline void rlwimi( Register a, Register s, int sh5, int mb5, int me5); 1.1341 + inline void insrdi( Register a, Register s, int n, int b); 1.1342 + inline void insrwi( Register a, Register s, int n, int b); 1.1343 + 1.1344 + // PPC 1, section 3.3.2 Fixed-Point Load Instructions 1.1345 + // 4 bytes 1.1346 + inline void lwzx( Register d, Register s1, Register s2); 1.1347 + inline void lwz( Register d, int si16, Register s1); 1.1348 + inline void lwzu( Register d, int si16, Register s1); 1.1349 + 1.1350 + // 4 bytes 1.1351 + inline void lwax( Register d, Register s1, Register s2); 1.1352 + inline void lwa( Register d, int si16, Register s1); 1.1353 + 1.1354 + // 2 bytes 1.1355 + inline void lhzx( Register d, Register s1, Register s2); 1.1356 + inline void lhz( Register d, int si16, Register s1); 1.1357 + inline void lhzu( Register d, int si16, Register s1); 1.1358 + 1.1359 + // 2 bytes 1.1360 + inline void lhax( Register d, Register s1, Register s2); 1.1361 + inline void lha( Register d, int si16, Register s1); 1.1362 + inline void lhau( Register d, int si16, Register s1); 1.1363 + 1.1364 + // 1 byte 1.1365 + inline void lbzx( Register d, Register s1, Register s2); 1.1366 + inline void lbz( Register d, int si16, Register s1); 1.1367 + inline void lbzu( Register d, int si16, Register s1); 1.1368 + 1.1369 + // 8 bytes 1.1370 + inline void ldx( Register d, Register s1, Register s2); 1.1371 + inline void ld( Register d, int si16, Register s1); 1.1372 + inline void ldu( Register d, int si16, Register s1); 1.1373 + 1.1374 + // PPC 1, section 3.3.3 Fixed-Point Store Instructions 1.1375 + inline void stwx( Register d, Register s1, Register s2); 1.1376 + inline void stw( Register d, int si16, Register s1); 1.1377 + inline void stwu( Register d, int si16, Register s1); 1.1378 + 1.1379 + inline void sthx( Register d, Register s1, Register s2); 1.1380 + inline void sth( Register d, int si16, Register s1); 1.1381 + inline void sthu( Register d, int si16, Register s1); 1.1382 + 1.1383 + inline void stbx( Register d, Register s1, Register s2); 1.1384 + inline void stb( Register d, int si16, Register s1); 1.1385 + inline void stbu( Register d, int si16, Register s1); 1.1386 + 1.1387 + inline void stdx( Register d, Register s1, Register s2); 1.1388 + inline void std( Register d, int si16, Register s1); 1.1389 + inline void stdu( Register d, int si16, Register s1); 1.1390 + inline void stdux(Register s, Register a, Register b); 1.1391 + 1.1392 + // PPC 1, section 3.3.13 Move To/From System Register Instructions 1.1393 + inline void mtlr( Register s1); 1.1394 + inline void mflr( Register d); 1.1395 + inline void mtctr(Register s1); 1.1396 + inline void mfctr(Register d); 1.1397 + inline void mtcrf(int fxm, Register s); 1.1398 + inline void mfcr( Register d); 1.1399 + inline void mcrf( ConditionRegister crd, ConditionRegister cra); 1.1400 + inline void mtcr( Register s); 1.1401 + 1.1402 + // PPC 1, section 2.4.1 Branch Instructions 1.1403 + inline void b( address a, relocInfo::relocType rt = relocInfo::none); 1.1404 + inline void b( Label& L); 1.1405 + inline void bl( address a, relocInfo::relocType rt = relocInfo::none); 1.1406 + inline void bl( Label& L); 1.1407 + inline void bc( int boint, int biint, address a, relocInfo::relocType rt = relocInfo::none); 1.1408 + inline void bc( int boint, int biint, Label& L); 1.1409 + inline void bcl(int boint, int biint, address a, relocInfo::relocType rt = relocInfo::none); 1.1410 + inline void bcl(int boint, int biint, Label& L); 1.1411 + 1.1412 + inline void bclr( int boint, int biint, int bhint, relocInfo::relocType rt = relocInfo::none); 1.1413 + inline void bclrl( int boint, int biint, int bhint, relocInfo::relocType rt = relocInfo::none); 1.1414 + inline void bcctr( int boint, int biint, int bhint = bhintbhBCCTRisNotReturnButSame, 1.1415 + relocInfo::relocType rt = relocInfo::none); 1.1416 + inline void bcctrl(int boint, int biint, int bhint = bhintbhBCLRisReturn, 1.1417 + relocInfo::relocType rt = relocInfo::none); 1.1418 + 1.1419 + // helper function for b, bcxx 1.1420 + inline bool is_within_range_of_b(address a, address pc); 1.1421 + inline bool is_within_range_of_bcxx(address a, address pc); 1.1422 + 1.1423 + // get the destination of a bxx branch (b, bl, ba, bla) 1.1424 + static inline address bxx_destination(address baddr); 1.1425 + static inline address bxx_destination(int instr, address pc); 1.1426 + static inline intptr_t bxx_destination_offset(int instr, intptr_t bxx_pos); 1.1427 + 1.1428 + // extended mnemonics for branch instructions 1.1429 + inline void blt(ConditionRegister crx, Label& L); 1.1430 + inline void bgt(ConditionRegister crx, Label& L); 1.1431 + inline void beq(ConditionRegister crx, Label& L); 1.1432 + inline void bso(ConditionRegister crx, Label& L); 1.1433 + inline void bge(ConditionRegister crx, Label& L); 1.1434 + inline void ble(ConditionRegister crx, Label& L); 1.1435 + inline void bne(ConditionRegister crx, Label& L); 1.1436 + inline void bns(ConditionRegister crx, Label& L); 1.1437 + 1.1438 + // Branch instructions with static prediction hints. 1.1439 + inline void blt_predict_taken( ConditionRegister crx, Label& L); 1.1440 + inline void bgt_predict_taken( ConditionRegister crx, Label& L); 1.1441 + inline void beq_predict_taken( ConditionRegister crx, Label& L); 1.1442 + inline void bso_predict_taken( ConditionRegister crx, Label& L); 1.1443 + inline void bge_predict_taken( ConditionRegister crx, Label& L); 1.1444 + inline void ble_predict_taken( ConditionRegister crx, Label& L); 1.1445 + inline void bne_predict_taken( ConditionRegister crx, Label& L); 1.1446 + inline void bns_predict_taken( ConditionRegister crx, Label& L); 1.1447 + inline void blt_predict_not_taken(ConditionRegister crx, Label& L); 1.1448 + inline void bgt_predict_not_taken(ConditionRegister crx, Label& L); 1.1449 + inline void beq_predict_not_taken(ConditionRegister crx, Label& L); 1.1450 + inline void bso_predict_not_taken(ConditionRegister crx, Label& L); 1.1451 + inline void bge_predict_not_taken(ConditionRegister crx, Label& L); 1.1452 + inline void ble_predict_not_taken(ConditionRegister crx, Label& L); 1.1453 + inline void bne_predict_not_taken(ConditionRegister crx, Label& L); 1.1454 + inline void bns_predict_not_taken(ConditionRegister crx, Label& L); 1.1455 + 1.1456 + // for use in conjunction with testbitdi: 1.1457 + inline void btrue( ConditionRegister crx, Label& L); 1.1458 + inline void bfalse(ConditionRegister crx, Label& L); 1.1459 + 1.1460 + inline void bltl(ConditionRegister crx, Label& L); 1.1461 + inline void bgtl(ConditionRegister crx, Label& L); 1.1462 + inline void beql(ConditionRegister crx, Label& L); 1.1463 + inline void bsol(ConditionRegister crx, Label& L); 1.1464 + inline void bgel(ConditionRegister crx, Label& L); 1.1465 + inline void blel(ConditionRegister crx, Label& L); 1.1466 + inline void bnel(ConditionRegister crx, Label& L); 1.1467 + inline void bnsl(ConditionRegister crx, Label& L); 1.1468 + 1.1469 + // extended mnemonics for Branch Instructions via LR 1.1470 + // We use `blr' for returns. 1.1471 + inline void blr(relocInfo::relocType rt = relocInfo::none); 1.1472 + 1.1473 + // extended mnemonics for Branch Instructions with CTR 1.1474 + // bdnz means `decrement CTR and jump to L if CTR is not zero' 1.1475 + inline void bdnz(Label& L); 1.1476 + // Decrement and branch if result is zero. 1.1477 + inline void bdz(Label& L); 1.1478 + // we use `bctr[l]' for jumps/calls in function descriptor glue 1.1479 + // code, e.g. calls to runtime functions 1.1480 + inline void bctr( relocInfo::relocType rt = relocInfo::none); 1.1481 + inline void bctrl(relocInfo::relocType rt = relocInfo::none); 1.1482 + // conditional jumps/branches via CTR 1.1483 + inline void beqctr( ConditionRegister crx, relocInfo::relocType rt = relocInfo::none); 1.1484 + inline void beqctrl(ConditionRegister crx, relocInfo::relocType rt = relocInfo::none); 1.1485 + inline void bnectr( ConditionRegister crx, relocInfo::relocType rt = relocInfo::none); 1.1486 + inline void bnectrl(ConditionRegister crx, relocInfo::relocType rt = relocInfo::none); 1.1487 + 1.1488 + // condition register logic instructions 1.1489 + inline void crand( int d, int s1, int s2); 1.1490 + inline void crnand(int d, int s1, int s2); 1.1491 + inline void cror( int d, int s1, int s2); 1.1492 + inline void crxor( int d, int s1, int s2); 1.1493 + inline void crnor( int d, int s1, int s2); 1.1494 + inline void creqv( int d, int s1, int s2); 1.1495 + inline void crandc(int d, int s1, int s2); 1.1496 + inline void crorc( int d, int s1, int s2); 1.1497 + 1.1498 + // icache and dcache related instructions 1.1499 + inline void icbi( Register s1, Register s2); 1.1500 + //inline void dcba(Register s1, Register s2); // Instruction for embedded processor only. 1.1501 + inline void dcbz( Register s1, Register s2); 1.1502 + inline void dcbst( Register s1, Register s2); 1.1503 + inline void dcbf( Register s1, Register s2); 1.1504 + 1.1505 + enum ct_cache_specification { 1.1506 + ct_primary_cache = 0, 1.1507 + ct_secondary_cache = 2 1.1508 + }; 1.1509 + // dcache read hint 1.1510 + inline void dcbt( Register s1, Register s2); 1.1511 + inline void dcbtct( Register s1, Register s2, int ct); 1.1512 + inline void dcbtds( Register s1, Register s2, int ds); 1.1513 + // dcache write hint 1.1514 + inline void dcbtst( Register s1, Register s2); 1.1515 + inline void dcbtstct(Register s1, Register s2, int ct); 1.1516 + 1.1517 + // machine barrier instructions: 1.1518 + // 1.1519 + // - sync two-way memory barrier, aka fence 1.1520 + // - lwsync orders Store|Store, 1.1521 + // Load|Store, 1.1522 + // Load|Load, 1.1523 + // but not Store|Load 1.1524 + // - eieio orders memory accesses for device memory (only) 1.1525 + // - isync invalidates speculatively executed instructions 1.1526 + // From the Power ISA 2.06 documentation: 1.1527 + // "[...] an isync instruction prevents the execution of 1.1528 + // instructions following the isync until instructions 1.1529 + // preceding the isync have completed, [...]" 1.1530 + // From IBM's AIX assembler reference: 1.1531 + // "The isync [...] instructions causes the processor to 1.1532 + // refetch any instructions that might have been fetched 1.1533 + // prior to the isync instruction. The instruction isync 1.1534 + // causes the processor to wait for all previous instructions 1.1535 + // to complete. Then any instructions already fetched are 1.1536 + // discarded and instruction processing continues in the 1.1537 + // environment established by the previous instructions." 1.1538 + // 1.1539 + // semantic barrier instructions: 1.1540 + // (as defined in orderAccess.hpp) 1.1541 + // 1.1542 + // - release orders Store|Store, (maps to lwsync) 1.1543 + // Load|Store 1.1544 + // - acquire orders Load|Store, (maps to lwsync) 1.1545 + // Load|Load 1.1546 + // - fence orders Store|Store, (maps to sync) 1.1547 + // Load|Store, 1.1548 + // Load|Load, 1.1549 + // Store|Load 1.1550 + // 1.1551 + private: 1.1552 + inline void sync(int l); 1.1553 + public: 1.1554 + inline void sync(); 1.1555 + inline void lwsync(); 1.1556 + inline void ptesync(); 1.1557 + inline void eieio(); 1.1558 + inline void isync(); 1.1559 + 1.1560 + inline void release(); 1.1561 + inline void acquire(); 1.1562 + inline void fence(); 1.1563 + 1.1564 + // atomics 1.1565 + inline void lwarx_unchecked(Register d, Register a, Register b, int eh1 = 0); 1.1566 + inline void ldarx_unchecked(Register d, Register a, Register b, int eh1 = 0); 1.1567 + inline bool lxarx_hint_exclusive_access(); 1.1568 + inline void lwarx( Register d, Register a, Register b, bool hint_exclusive_access = false); 1.1569 + inline void ldarx( Register d, Register a, Register b, bool hint_exclusive_access = false); 1.1570 + inline void stwcx_( Register s, Register a, Register b); 1.1571 + inline void stdcx_( Register s, Register a, Register b); 1.1572 + 1.1573 + // Instructions for adjusting thread priority for simultaneous 1.1574 + // multithreading (SMT) on Power5. 1.1575 + private: 1.1576 + inline void smt_prio_very_low(); 1.1577 + inline void smt_prio_medium_high(); 1.1578 + inline void smt_prio_high(); 1.1579 + 1.1580 + public: 1.1581 + inline void smt_prio_low(); 1.1582 + inline void smt_prio_medium_low(); 1.1583 + inline void smt_prio_medium(); 1.1584 + 1.1585 + // trap instructions 1.1586 + inline void twi_0(Register a); // for load with acquire semantics use load+twi_0+isync (trap can't occur) 1.1587 + // NOT FOR DIRECT USE!! 1.1588 + protected: 1.1589 + inline void tdi_unchecked(int tobits, Register a, int si16); 1.1590 + inline void twi_unchecked(int tobits, Register a, int si16); 1.1591 + inline void tdi( int tobits, Register a, int si16); // asserts UseSIGTRAP 1.1592 + inline void twi( int tobits, Register a, int si16); // asserts UseSIGTRAP 1.1593 + inline void td( int tobits, Register a, Register b); // asserts UseSIGTRAP 1.1594 + inline void tw( int tobits, Register a, Register b); // asserts UseSIGTRAP 1.1595 + 1.1596 + static bool is_tdi(int x, int tobits, int ra, int si16) { 1.1597 + return (TDI_OPCODE == (x & TDI_OPCODE_MASK)) 1.1598 + && (tobits == inv_to_field(x)) 1.1599 + && (ra == -1/*any reg*/ || ra == inv_ra_field(x)) 1.1600 + && (si16 == inv_si_field(x)); 1.1601 + } 1.1602 + 1.1603 + static bool is_twi(int x, int tobits, int ra, int si16) { 1.1604 + return (TWI_OPCODE == (x & TWI_OPCODE_MASK)) 1.1605 + && (tobits == inv_to_field(x)) 1.1606 + && (ra == -1/*any reg*/ || ra == inv_ra_field(x)) 1.1607 + && (si16 == inv_si_field(x)); 1.1608 + } 1.1609 + 1.1610 + static bool is_twi(int x, int tobits, int ra) { 1.1611 + return (TWI_OPCODE == (x & TWI_OPCODE_MASK)) 1.1612 + && (tobits == inv_to_field(x)) 1.1613 + && (ra == -1/*any reg*/ || ra == inv_ra_field(x)); 1.1614 + } 1.1615 + 1.1616 + static bool is_td(int x, int tobits, int ra, int rb) { 1.1617 + return (TD_OPCODE == (x & TD_OPCODE_MASK)) 1.1618 + && (tobits == inv_to_field(x)) 1.1619 + && (ra == -1/*any reg*/ || ra == inv_ra_field(x)) 1.1620 + && (rb == -1/*any reg*/ || rb == inv_rb_field(x)); 1.1621 + } 1.1622 + 1.1623 + static bool is_tw(int x, int tobits, int ra, int rb) { 1.1624 + return (TW_OPCODE == (x & TW_OPCODE_MASK)) 1.1625 + && (tobits == inv_to_field(x)) 1.1626 + && (ra == -1/*any reg*/ || ra == inv_ra_field(x)) 1.1627 + && (rb == -1/*any reg*/ || rb == inv_rb_field(x)); 1.1628 + } 1.1629 + 1.1630 + public: 1.1631 + // PPC floating point instructions 1.1632 + // PPC 1, section 4.6.2 Floating-Point Load Instructions 1.1633 + inline void lfs( FloatRegister d, int si16, Register a); 1.1634 + inline void lfsu( FloatRegister d, int si16, Register a); 1.1635 + inline void lfsx( FloatRegister d, Register a, Register b); 1.1636 + inline void lfd( FloatRegister d, int si16, Register a); 1.1637 + inline void lfdu( FloatRegister d, int si16, Register a); 1.1638 + inline void lfdx( FloatRegister d, Register a, Register b); 1.1639 + 1.1640 + // PPC 1, section 4.6.3 Floating-Point Store Instructions 1.1641 + inline void stfs( FloatRegister s, int si16, Register a); 1.1642 + inline void stfsu( FloatRegister s, int si16, Register a); 1.1643 + inline void stfsx( FloatRegister s, Register a, Register b); 1.1644 + inline void stfd( FloatRegister s, int si16, Register a); 1.1645 + inline void stfdu( FloatRegister s, int si16, Register a); 1.1646 + inline void stfdx( FloatRegister s, Register a, Register b); 1.1647 + 1.1648 + // PPC 1, section 4.6.4 Floating-Point Move Instructions 1.1649 + inline void fmr( FloatRegister d, FloatRegister b); 1.1650 + inline void fmr_( FloatRegister d, FloatRegister b); 1.1651 + 1.1652 + // inline void mffgpr( FloatRegister d, Register b); 1.1653 + // inline void mftgpr( Register d, FloatRegister b); 1.1654 + inline void cmpb( Register a, Register s, Register b); 1.1655 + inline void popcntb(Register a, Register s); 1.1656 + inline void popcntw(Register a, Register s); 1.1657 + inline void popcntd(Register a, Register s); 1.1658 + 1.1659 + inline void fneg( FloatRegister d, FloatRegister b); 1.1660 + inline void fneg_( FloatRegister d, FloatRegister b); 1.1661 + inline void fabs( FloatRegister d, FloatRegister b); 1.1662 + inline void fabs_( FloatRegister d, FloatRegister b); 1.1663 + inline void fnabs( FloatRegister d, FloatRegister b); 1.1664 + inline void fnabs_(FloatRegister d, FloatRegister b); 1.1665 + 1.1666 + // PPC 1, section 4.6.5.1 Floating-Point Elementary Arithmetic Instructions 1.1667 + inline void fadd( FloatRegister d, FloatRegister a, FloatRegister b); 1.1668 + inline void fadd_( FloatRegister d, FloatRegister a, FloatRegister b); 1.1669 + inline void fadds( FloatRegister d, FloatRegister a, FloatRegister b); 1.1670 + inline void fadds_(FloatRegister d, FloatRegister a, FloatRegister b); 1.1671 + inline void fsub( FloatRegister d, FloatRegister a, FloatRegister b); 1.1672 + inline void fsub_( FloatRegister d, FloatRegister a, FloatRegister b); 1.1673 + inline void fsubs( FloatRegister d, FloatRegister a, FloatRegister b); 1.1674 + inline void fsubs_(FloatRegister d, FloatRegister a, FloatRegister b); 1.1675 + inline void fmul( FloatRegister d, FloatRegister a, FloatRegister c); 1.1676 + inline void fmul_( FloatRegister d, FloatRegister a, FloatRegister c); 1.1677 + inline void fmuls( FloatRegister d, FloatRegister a, FloatRegister c); 1.1678 + inline void fmuls_(FloatRegister d, FloatRegister a, FloatRegister c); 1.1679 + inline void fdiv( FloatRegister d, FloatRegister a, FloatRegister b); 1.1680 + inline void fdiv_( FloatRegister d, FloatRegister a, FloatRegister b); 1.1681 + inline void fdivs( FloatRegister d, FloatRegister a, FloatRegister b); 1.1682 + inline void fdivs_(FloatRegister d, FloatRegister a, FloatRegister b); 1.1683 + 1.1684 + // PPC 1, section 4.6.6 Floating-Point Rounding and Conversion Instructions 1.1685 + inline void frsp( FloatRegister d, FloatRegister b); 1.1686 + inline void fctid( FloatRegister d, FloatRegister b); 1.1687 + inline void fctidz(FloatRegister d, FloatRegister b); 1.1688 + inline void fctiw( FloatRegister d, FloatRegister b); 1.1689 + inline void fctiwz(FloatRegister d, FloatRegister b); 1.1690 + inline void fcfid( FloatRegister d, FloatRegister b); 1.1691 + inline void fcfids(FloatRegister d, FloatRegister b); 1.1692 + 1.1693 + // PPC 1, section 4.6.7 Floating-Point Compare Instructions 1.1694 + inline void fcmpu( ConditionRegister crx, FloatRegister a, FloatRegister b); 1.1695 + 1.1696 + inline void fsqrt( FloatRegister d, FloatRegister b); 1.1697 + inline void fsqrts(FloatRegister d, FloatRegister b); 1.1698 + 1.1699 + // Vector instructions for >= Power6. 1.1700 + inline void lvebx( VectorRegister d, Register s1, Register s2); 1.1701 + inline void lvehx( VectorRegister d, Register s1, Register s2); 1.1702 + inline void lvewx( VectorRegister d, Register s1, Register s2); 1.1703 + inline void lvx( VectorRegister d, Register s1, Register s2); 1.1704 + inline void lvxl( VectorRegister d, Register s1, Register s2); 1.1705 + inline void stvebx( VectorRegister d, Register s1, Register s2); 1.1706 + inline void stvehx( VectorRegister d, Register s1, Register s2); 1.1707 + inline void stvewx( VectorRegister d, Register s1, Register s2); 1.1708 + inline void stvx( VectorRegister d, Register s1, Register s2); 1.1709 + inline void stvxl( VectorRegister d, Register s1, Register s2); 1.1710 + inline void lvsl( VectorRegister d, Register s1, Register s2); 1.1711 + inline void lvsr( VectorRegister d, Register s1, Register s2); 1.1712 + inline void vpkpx( VectorRegister d, VectorRegister a, VectorRegister b); 1.1713 + inline void vpkshss( VectorRegister d, VectorRegister a, VectorRegister b); 1.1714 + inline void vpkswss( VectorRegister d, VectorRegister a, VectorRegister b); 1.1715 + inline void vpkshus( VectorRegister d, VectorRegister a, VectorRegister b); 1.1716 + inline void vpkswus( VectorRegister d, VectorRegister a, VectorRegister b); 1.1717 + inline void vpkuhum( VectorRegister d, VectorRegister a, VectorRegister b); 1.1718 + inline void vpkuwum( VectorRegister d, VectorRegister a, VectorRegister b); 1.1719 + inline void vpkuhus( VectorRegister d, VectorRegister a, VectorRegister b); 1.1720 + inline void vpkuwus( VectorRegister d, VectorRegister a, VectorRegister b); 1.1721 + inline void vupkhpx( VectorRegister d, VectorRegister b); 1.1722 + inline void vupkhsb( VectorRegister d, VectorRegister b); 1.1723 + inline void vupkhsh( VectorRegister d, VectorRegister b); 1.1724 + inline void vupklpx( VectorRegister d, VectorRegister b); 1.1725 + inline void vupklsb( VectorRegister d, VectorRegister b); 1.1726 + inline void vupklsh( VectorRegister d, VectorRegister b); 1.1727 + inline void vmrghb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1728 + inline void vmrghw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1729 + inline void vmrghh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1730 + inline void vmrglb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1731 + inline void vmrglw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1732 + inline void vmrglh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1733 + inline void vsplt( VectorRegister d, int ui4, VectorRegister b); 1.1734 + inline void vsplth( VectorRegister d, int ui3, VectorRegister b); 1.1735 + inline void vspltw( VectorRegister d, int ui2, VectorRegister b); 1.1736 + inline void vspltisb( VectorRegister d, int si5); 1.1737 + inline void vspltish( VectorRegister d, int si5); 1.1738 + inline void vspltisw( VectorRegister d, int si5); 1.1739 + inline void vperm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1740 + inline void vsel( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1741 + inline void vsl( VectorRegister d, VectorRegister a, VectorRegister b); 1.1742 + inline void vsldoi( VectorRegister d, VectorRegister a, VectorRegister b, int si4); 1.1743 + inline void vslo( VectorRegister d, VectorRegister a, VectorRegister b); 1.1744 + inline void vsr( VectorRegister d, VectorRegister a, VectorRegister b); 1.1745 + inline void vsro( VectorRegister d, VectorRegister a, VectorRegister b); 1.1746 + inline void vaddcuw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1747 + inline void vaddshs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1748 + inline void vaddsbs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1749 + inline void vaddsws( VectorRegister d, VectorRegister a, VectorRegister b); 1.1750 + inline void vaddubm( VectorRegister d, VectorRegister a, VectorRegister b); 1.1751 + inline void vadduwm( VectorRegister d, VectorRegister a, VectorRegister b); 1.1752 + inline void vadduhm( VectorRegister d, VectorRegister a, VectorRegister b); 1.1753 + inline void vaddubs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1754 + inline void vadduws( VectorRegister d, VectorRegister a, VectorRegister b); 1.1755 + inline void vadduhs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1756 + inline void vsubcuw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1757 + inline void vsubshs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1758 + inline void vsubsbs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1759 + inline void vsubsws( VectorRegister d, VectorRegister a, VectorRegister b); 1.1760 + inline void vsububm( VectorRegister d, VectorRegister a, VectorRegister b); 1.1761 + inline void vsubuwm( VectorRegister d, VectorRegister a, VectorRegister b); 1.1762 + inline void vsubuhm( VectorRegister d, VectorRegister a, VectorRegister b); 1.1763 + inline void vsububs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1764 + inline void vsubuws( VectorRegister d, VectorRegister a, VectorRegister b); 1.1765 + inline void vsubuhs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1766 + inline void vmulesb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1767 + inline void vmuleub( VectorRegister d, VectorRegister a, VectorRegister b); 1.1768 + inline void vmulesh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1769 + inline void vmuleuh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1770 + inline void vmulosb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1771 + inline void vmuloub( VectorRegister d, VectorRegister a, VectorRegister b); 1.1772 + inline void vmulosh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1773 + inline void vmulouh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1774 + inline void vmhaddshs(VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1775 + inline void vmhraddshs(VectorRegister d,VectorRegister a, VectorRegister b, VectorRegister c); 1.1776 + inline void vmladduhm(VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1777 + inline void vmsubuhm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1778 + inline void vmsummbm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1779 + inline void vmsumshm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1780 + inline void vmsumshs( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1781 + inline void vmsumuhm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1782 + inline void vmsumuhs( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c); 1.1783 + inline void vsumsws( VectorRegister d, VectorRegister a, VectorRegister b); 1.1784 + inline void vsum2sws( VectorRegister d, VectorRegister a, VectorRegister b); 1.1785 + inline void vsum4sbs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1786 + inline void vsum4ubs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1787 + inline void vsum4shs( VectorRegister d, VectorRegister a, VectorRegister b); 1.1788 + inline void vavgsb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1789 + inline void vavgsw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1790 + inline void vavgsh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1791 + inline void vavgub( VectorRegister d, VectorRegister a, VectorRegister b); 1.1792 + inline void vavguw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1793 + inline void vavguh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1794 + inline void vmaxsb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1795 + inline void vmaxsw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1796 + inline void vmaxsh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1797 + inline void vmaxub( VectorRegister d, VectorRegister a, VectorRegister b); 1.1798 + inline void vmaxuw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1799 + inline void vmaxuh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1800 + inline void vminsb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1801 + inline void vminsw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1802 + inline void vminsh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1803 + inline void vminub( VectorRegister d, VectorRegister a, VectorRegister b); 1.1804 + inline void vminuw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1805 + inline void vminuh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1806 + inline void vcmpequb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1807 + inline void vcmpequh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1808 + inline void vcmpequw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1809 + inline void vcmpgtsh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1810 + inline void vcmpgtsb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1811 + inline void vcmpgtsw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1812 + inline void vcmpgtub( VectorRegister d, VectorRegister a, VectorRegister b); 1.1813 + inline void vcmpgtuh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1814 + inline void vcmpgtuw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1815 + inline void vcmpequb_(VectorRegister d, VectorRegister a, VectorRegister b); 1.1816 + inline void vcmpequh_(VectorRegister d, VectorRegister a, VectorRegister b); 1.1817 + inline void vcmpequw_(VectorRegister d, VectorRegister a, VectorRegister b); 1.1818 + inline void vcmpgtsh_(VectorRegister d, VectorRegister a, VectorRegister b); 1.1819 + inline void vcmpgtsb_(VectorRegister d, VectorRegister a, VectorRegister b); 1.1820 + inline void vcmpgtsw_(VectorRegister d, VectorRegister a, VectorRegister b); 1.1821 + inline void vcmpgtub_(VectorRegister d, VectorRegister a, VectorRegister b); 1.1822 + inline void vcmpgtuh_(VectorRegister d, VectorRegister a, VectorRegister b); 1.1823 + inline void vcmpgtuw_(VectorRegister d, VectorRegister a, VectorRegister b); 1.1824 + inline void vand( VectorRegister d, VectorRegister a, VectorRegister b); 1.1825 + inline void vandc( VectorRegister d, VectorRegister a, VectorRegister b); 1.1826 + inline void vnor( VectorRegister d, VectorRegister a, VectorRegister b); 1.1827 + inline void vor( VectorRegister d, VectorRegister a, VectorRegister b); 1.1828 + inline void vxor( VectorRegister d, VectorRegister a, VectorRegister b); 1.1829 + inline void vrlb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1830 + inline void vrlw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1831 + inline void vrlh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1832 + inline void vslb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1833 + inline void vskw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1834 + inline void vslh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1835 + inline void vsrb( VectorRegister d, VectorRegister a, VectorRegister b); 1.1836 + inline void vsrw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1837 + inline void vsrh( VectorRegister d, VectorRegister a, VectorRegister b); 1.1838 + inline void vsrab( VectorRegister d, VectorRegister a, VectorRegister b); 1.1839 + inline void vsraw( VectorRegister d, VectorRegister a, VectorRegister b); 1.1840 + inline void vsrah( VectorRegister d, VectorRegister a, VectorRegister b); 1.1841 + // Vector Floating-Point not implemented yet 1.1842 + inline void mtvscr( VectorRegister b); 1.1843 + inline void mfvscr( VectorRegister d); 1.1844 + 1.1845 + // The following encoders use r0 as second operand. These instructions 1.1846 + // read r0 as '0'. 1.1847 + inline void lwzx( Register d, Register s2); 1.1848 + inline void lwz( Register d, int si16); 1.1849 + inline void lwax( Register d, Register s2); 1.1850 + inline void lwa( Register d, int si16); 1.1851 + inline void lhzx( Register d, Register s2); 1.1852 + inline void lhz( Register d, int si16); 1.1853 + inline void lhax( Register d, Register s2); 1.1854 + inline void lha( Register d, int si16); 1.1855 + inline void lbzx( Register d, Register s2); 1.1856 + inline void lbz( Register d, int si16); 1.1857 + inline void ldx( Register d, Register s2); 1.1858 + inline void ld( Register d, int si16); 1.1859 + inline void stwx( Register d, Register s2); 1.1860 + inline void stw( Register d, int si16); 1.1861 + inline void sthx( Register d, Register s2); 1.1862 + inline void sth( Register d, int si16); 1.1863 + inline void stbx( Register d, Register s2); 1.1864 + inline void stb( Register d, int si16); 1.1865 + inline void stdx( Register d, Register s2); 1.1866 + inline void std( Register d, int si16); 1.1867 + 1.1868 + // PPC 2, section 3.2.1 Instruction Cache Instructions 1.1869 + inline void icbi( Register s2); 1.1870 + // PPC 2, section 3.2.2 Data Cache Instructions 1.1871 + //inlinevoid dcba( Register s2); // Instruction for embedded processor only. 1.1872 + inline void dcbz( Register s2); 1.1873 + inline void dcbst( Register s2); 1.1874 + inline void dcbf( Register s2); 1.1875 + // dcache read hint 1.1876 + inline void dcbt( Register s2); 1.1877 + inline void dcbtct( Register s2, int ct); 1.1878 + inline void dcbtds( Register s2, int ds); 1.1879 + // dcache write hint 1.1880 + inline void dcbtst( Register s2); 1.1881 + inline void dcbtstct(Register s2, int ct); 1.1882 + 1.1883 + // Atomics: use ra0mem to disallow R0 as base. 1.1884 + inline void lwarx_unchecked(Register d, Register b, int eh1); 1.1885 + inline void ldarx_unchecked(Register d, Register b, int eh1); 1.1886 + inline void lwarx( Register d, Register b, bool hint_exclusive_access); 1.1887 + inline void ldarx( Register d, Register b, bool hint_exclusive_access); 1.1888 + inline void stwcx_(Register s, Register b); 1.1889 + inline void stdcx_(Register s, Register b); 1.1890 + inline void lfs( FloatRegister d, int si16); 1.1891 + inline void lfsx( FloatRegister d, Register b); 1.1892 + inline void lfd( FloatRegister d, int si16); 1.1893 + inline void lfdx( FloatRegister d, Register b); 1.1894 + inline void stfs( FloatRegister s, int si16); 1.1895 + inline void stfsx( FloatRegister s, Register b); 1.1896 + inline void stfd( FloatRegister s, int si16); 1.1897 + inline void stfdx( FloatRegister s, Register b); 1.1898 + inline void lvebx( VectorRegister d, Register s2); 1.1899 + inline void lvehx( VectorRegister d, Register s2); 1.1900 + inline void lvewx( VectorRegister d, Register s2); 1.1901 + inline void lvx( VectorRegister d, Register s2); 1.1902 + inline void lvxl( VectorRegister d, Register s2); 1.1903 + inline void stvebx(VectorRegister d, Register s2); 1.1904 + inline void stvehx(VectorRegister d, Register s2); 1.1905 + inline void stvewx(VectorRegister d, Register s2); 1.1906 + inline void stvx( VectorRegister d, Register s2); 1.1907 + inline void stvxl( VectorRegister d, Register s2); 1.1908 + inline void lvsl( VectorRegister d, Register s2); 1.1909 + inline void lvsr( VectorRegister d, Register s2); 1.1910 + 1.1911 + // RegisterOrConstant versions. 1.1912 + // These emitters choose between the versions using two registers and 1.1913 + // those with register and immediate, depending on the content of roc. 1.1914 + // If the constant is not encodable as immediate, instructions to 1.1915 + // load the constant are emitted beforehand. Store instructions need a 1.1916 + // tmp reg if the constant is not encodable as immediate. 1.1917 + // Size unpredictable. 1.1918 + void ld( Register d, RegisterOrConstant roc, Register s1 = noreg); 1.1919 + void lwa( Register d, RegisterOrConstant roc, Register s1 = noreg); 1.1920 + void lwz( Register d, RegisterOrConstant roc, Register s1 = noreg); 1.1921 + void lha( Register d, RegisterOrConstant roc, Register s1 = noreg); 1.1922 + void lhz( Register d, RegisterOrConstant roc, Register s1 = noreg); 1.1923 + void lbz( Register d, RegisterOrConstant roc, Register s1 = noreg); 1.1924 + void std( Register d, RegisterOrConstant roc, Register s1 = noreg, Register tmp = noreg); 1.1925 + void stw( Register d, RegisterOrConstant roc, Register s1 = noreg, Register tmp = noreg); 1.1926 + void sth( Register d, RegisterOrConstant roc, Register s1 = noreg, Register tmp = noreg); 1.1927 + void stb( Register d, RegisterOrConstant roc, Register s1 = noreg, Register tmp = noreg); 1.1928 + void add( Register d, RegisterOrConstant roc, Register s1); 1.1929 + void subf(Register d, RegisterOrConstant roc, Register s1); 1.1930 + void cmpd(ConditionRegister d, RegisterOrConstant roc, Register s1); 1.1931 + 1.1932 + 1.1933 + // Emit several instructions to load a 64 bit constant. This issues a fixed 1.1934 + // instruction pattern so that the constant can be patched later on. 1.1935 + enum { 1.1936 + load_const_size = 5 * BytesPerInstWord 1.1937 + }; 1.1938 + void load_const(Register d, long a, Register tmp = noreg); 1.1939 + inline void load_const(Register d, void* a, Register tmp = noreg); 1.1940 + inline void load_const(Register d, Label& L, Register tmp = noreg); 1.1941 + inline void load_const(Register d, AddressLiteral& a, Register tmp = noreg); 1.1942 + 1.1943 + // Load a 64 bit constant, optimized, not identifyable. 1.1944 + // Tmp can be used to increase ILP. Set return_simm16_rest=true to get a 1.1945 + // 16 bit immediate offset. This is useful if the offset can be encoded in 1.1946 + // a succeeding instruction. 1.1947 + int load_const_optimized(Register d, long a, Register tmp = noreg, bool return_simm16_rest = false); 1.1948 + inline int load_const_optimized(Register d, void* a, Register tmp = noreg, bool return_simm16_rest = false) { 1.1949 + return load_const_optimized(d, (long)(unsigned long)a, tmp, return_simm16_rest); 1.1950 + } 1.1951 + 1.1952 + // Creation 1.1953 + Assembler(CodeBuffer* code) : AbstractAssembler(code) { 1.1954 +#ifdef CHECK_DELAY 1.1955 + delay_state = no_delay; 1.1956 +#endif 1.1957 + } 1.1958 + 1.1959 + // Testing 1.1960 +#ifndef PRODUCT 1.1961 + void test_asm(); 1.1962 +#endif 1.1963 +}; 1.1964 + 1.1965 + 1.1966 +#endif // CPU_PPC_VM_ASSEMBLER_PPC_HPP