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