Wed, 29 Mar 2017 09:41:51 +0800
#4662 TieredCompilation is turned off.
TieredCompilation is not supported yet.
aoqi@208 | 1 | /* |
aoqi@208 | 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
aoqi@208 | 3 | * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved. |
aoqi@208 | 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@208 | 5 | * |
aoqi@208 | 6 | * This code is free software; you can redistribute it and/or modify it |
aoqi@208 | 7 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@208 | 8 | * published by the Free Software Foundation. |
aoqi@208 | 9 | * |
aoqi@208 | 10 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@208 | 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@208 | 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@208 | 13 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@208 | 14 | * accompanied this code). |
aoqi@208 | 15 | * |
aoqi@208 | 16 | * You should have received a copy of the GNU General Public License version |
aoqi@208 | 17 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@208 | 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@208 | 19 | * |
aoqi@208 | 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@208 | 21 | * or visit www.oracle.com if you need additional information or have any |
aoqi@208 | 22 | * questions. |
aoqi@208 | 23 | * |
aoqi@208 | 24 | */ |
aoqi@208 | 25 | |
aoqi@208 | 26 | #ifdef USE_PRAGMA_IDENT_SRC |
aoqi@208 | 27 | #pragma ident "@(#)disassembler_mips.cpp 1.35 03/12/23 16:36:14 JVM" |
aoqi@208 | 28 | #endif |
aoqi@208 | 29 | # include "precompiled.hpp" |
aoqi@208 | 30 | # include "depChecker_mips.hpp" |
aoqi@208 | 31 | # include "runtime/fprofiler.hpp" |
aoqi@208 | 32 | |
aoqi@208 | 33 | |
aoqi@208 | 34 | class mips32_env : public DisassemblerEnv { |
aoqi@208 | 35 | private: |
aoqi@208 | 36 | nmethod* code; |
aoqi@208 | 37 | outputStream* output; |
aoqi@208 | 38 | public: |
aoqi@208 | 39 | mips32_env(nmethod* rcode, outputStream* routput) { |
aoqi@208 | 40 | code = rcode; |
aoqi@208 | 41 | output = routput; |
aoqi@208 | 42 | } |
aoqi@208 | 43 | void print_label(intptr_t value); |
aoqi@208 | 44 | void print_raw(const char* str) { output->print_raw(str); } |
aoqi@208 | 45 | void print(const char* format, ...); |
aoqi@208 | 46 | char* string_for_offset(intptr_t value); |
aoqi@208 | 47 | char* string_for_constant(unsigned char* pc, intptr_t value, int is_decimal); |
aoqi@208 | 48 | }; |
aoqi@208 | 49 | |
aoqi@208 | 50 | |
aoqi@208 | 51 | void mips32_env::print_label(intptr_t value) { |
aoqi@208 | 52 | if (!Universe::is_fully_initialized()) { |
aoqi@208 | 53 | output->print(INTPTR_FORMAT, value); |
aoqi@208 | 54 | return; |
aoqi@208 | 55 | } |
aoqi@208 | 56 | address adr = (address) value; |
aoqi@208 | 57 | if (StubRoutines::contains(adr)) { |
aoqi@208 | 58 | StubCodeDesc* desc = StubCodeDesc::desc_for(adr); |
aoqi@208 | 59 | const char * desc_name = "unknown stub"; |
aoqi@208 | 60 | if (desc != NULL) { |
aoqi@208 | 61 | desc_name = desc->name(); |
aoqi@208 | 62 | } |
aoqi@208 | 63 | output->print("Stub::%s", desc_name); |
aoqi@208 | 64 | if (WizardMode) output->print(" " INTPTR_FORMAT, value); |
aoqi@208 | 65 | } else { |
aoqi@208 | 66 | output->print(INTPTR_FORMAT, value); |
aoqi@208 | 67 | } |
aoqi@208 | 68 | } |
aoqi@208 | 69 | |
aoqi@208 | 70 | void mips32_env::print(const char* format, ...) { |
aoqi@208 | 71 | va_list ap; |
aoqi@208 | 72 | va_start(ap, format); |
aoqi@208 | 73 | output->vprint(format, ap); |
aoqi@208 | 74 | va_end(ap); |
aoqi@208 | 75 | } |
aoqi@208 | 76 | |
aoqi@208 | 77 | char* mips32_env::string_for_offset(intptr_t value) { |
aoqi@208 | 78 | stringStream st; |
aoqi@208 | 79 | if (!Universe::is_fully_initialized()) { |
aoqi@208 | 80 | st.print("%d", value); |
aoqi@208 | 81 | return st.as_string(); |
aoqi@208 | 82 | } |
aoqi@208 | 83 | BarrierSet* bs = Universe::heap()->barrier_set(); |
aoqi@208 | 84 | BarrierSet::Name bsn = bs->kind(); |
aoqi@208 | 85 | |
aoqi@208 | 86 | if (bs->kind() == BarrierSet::CardTableModRef && (jbyte*) value == ((CardTableModRefBS*)(bs))->byte_map_base) { |
aoqi@208 | 87 | st.print("word_map_base"); |
aoqi@208 | 88 | } else { |
aoqi@208 | 89 | st.print("%d", value); |
aoqi@208 | 90 | } |
aoqi@208 | 91 | return st.as_string(); |
aoqi@208 | 92 | } |
aoqi@208 | 93 | |
aoqi@208 | 94 | char* mips32_env::string_for_constant(unsigned char* pc, intptr_t value, int is_decimal) { |
aoqi@208 | 95 | stringStream st; |
aoqi@208 | 96 | oop obj = NULL; |
aoqi@208 | 97 | #ifndef CORE |
aoqi@208 | 98 | if (code && (obj = code->embeddedOop_at(pc))!=NULL) { |
aoqi@208 | 99 | obj->print_value_on(&st); |
aoqi@208 | 100 | } else |
aoqi@208 | 101 | #endif |
aoqi@208 | 102 | { |
aoqi@208 | 103 | if (is_decimal == 1) { |
aoqi@208 | 104 | st.print("%d", value); |
aoqi@208 | 105 | } else { |
aoqi@208 | 106 | st.print("0x%lx", value); |
aoqi@208 | 107 | } |
aoqi@208 | 108 | } |
aoqi@208 | 109 | return st.as_string(); |
aoqi@208 | 110 | } |
aoqi@208 | 111 | |
aoqi@208 | 112 | #define PRINT_NOP() \ |
aoqi@208 | 113 | env->print("nop"); |
aoqi@208 | 114 | |
aoqi@208 | 115 | #define PRINT_ORRI(OP) \ |
aoqi@208 | 116 | env->print("%s %s, %s, 0x%x", OP, as_Register(Assembler::rt(insn))->name(), \ |
aoqi@208 | 117 | as_Register(Assembler::rs(insn))->name(), \ |
aoqi@208 | 118 | (short)Assembler::low16(insn) ) |
aoqi@208 | 119 | |
aoqi@208 | 120 | #define PRINT_ORRL(OP) \ |
aoqi@208 | 121 | env->print("%s %s, %s, ", OP, as_Register(Assembler::rs(insn))->name(), \ |
aoqi@208 | 122 | as_Register(Assembler::rt(insn))->name()); \ |
aoqi@208 | 123 | env->print_label( (intptr_t)start + 4 + ((short)Assembler::low16(insn)<<2) ) |
aoqi@208 | 124 | |
aoqi@208 | 125 | #define PRINT_J(OP) \ |
fujie@379 | 126 | env->print("%s ", (char*)OP); \ |
aoqi@208 | 127 | env->print_label( ( ( (intptr_t)start + 4 ) & 0xc0000000 ) | ( Assembler::low26(insn) << 2 ) ); \ |
aoqi@208 | 128 | env->print(""); |
aoqi@208 | 129 | |
aoqi@208 | 130 | #define PRINT_ORSL(OP) \ |
aoqi@208 | 131 | env->print("%s %s, ", OP, as_Register(Assembler::rs(insn))->name()); \ |
aoqi@208 | 132 | env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) ); \ |
aoqi@208 | 133 | env->print(""); |
aoqi@208 | 134 | |
aoqi@208 | 135 | #define PRINT_OROB(OP) \ |
aoqi@208 | 136 | env->print("%s %s, 0x%x(%s)", OP, as_Register(Assembler::rt(insn))->name(), \ |
aoqi@208 | 137 | (short)Assembler::low16(insn), \ |
aoqi@208 | 138 | as_Register(Assembler::rs(insn))->name() ) |
aoqi@208 | 139 | |
aoqi@208 | 140 | #define PRINT_OFOB(OP) \ |
aoqi@208 | 141 | env->print("%s %s, 0x%x(%s)", OP, as_FloatRegister(Assembler::rt(insn))->name(), \ |
aoqi@208 | 142 | (short)Assembler::low16(insn), \ |
aoqi@208 | 143 | as_Register(Assembler::rs(insn))->name() ) |
aoqi@208 | 144 | |
aoqi@208 | 145 | |
aoqi@208 | 146 | #define PRINT_ORRS(OP) \ |
aoqi@208 | 147 | env->print("%s %s, %s, %d", OP, as_Register(Assembler::rd(insn))->name(), \ |
aoqi@208 | 148 | as_Register(Assembler::rt(insn))->name(), \ |
aoqi@208 | 149 | Assembler::sa(insn) ) |
aoqi@208 | 150 | |
aoqi@208 | 151 | #define PRINT_ORRR(OP) \ |
aoqi@208 | 152 | env->print("%s %s, %s, %s", OP, as_Register(Assembler::rd(insn))->name(), \ |
aoqi@208 | 153 | as_Register(Assembler::rs(insn))->name(), \ |
aoqi@208 | 154 | as_Register(Assembler::rt(insn))->name() ) |
aoqi@208 | 155 | |
aoqi@208 | 156 | #define PRINT_ORRII(OP) \ |
chenhaoxuan@335 | 157 | env->print("%s %s, %s, 0x%x, 0x%x", OP,as_Register(Assembler::rt(insn))->name(), \ |
aoqi@208 | 158 | as_Register(Assembler::rs(insn))->name(), \ |
aoqi@208 | 159 | ((short)Assembler::low(insn, 11)), \ |
aoqi@208 | 160 | ((short)Assembler::low(insn, 6)) ) |
aoqi@208 | 161 | |
aoqi@208 | 162 | #define PRINT_ORRRI_GSLDC2(OP) \ |
aoqi@365 | 163 | env->print("%s %s, 0x%x(%s, %s)", OP, is_float?as_FloatRegister(Assembler::rt(insn))->name():as_Register(Assembler::rt(insn))->name(), \ |
aoqi@365 | 164 | ((short)Assembler::low(insn, 11) >> 3), \ |
aoqi@208 | 165 | as_Register(Assembler::rs(insn))->name(), \ |
aoqi@365 | 166 | as_Register(Assembler::rd(insn))->name()) |
aoqi@208 | 167 | |
aoqi@208 | 168 | #define PRINT_COP1X(OP) \ |
aoqi@208 | 169 | env->print("%s %s, %s, %s, %s", OP, as_FloatRegister(Assembler::sa(insn))->name(), \ |
aoqi@208 | 170 | as_FloatRegister(Assembler::rt(insn))->name(), \ |
aoqi@208 | 171 | as_FloatRegister(Assembler::rd(insn))->name(), \ |
aoqi@208 | 172 | as_FloatRegister(Assembler::rs(insn))->name()) |
aoqi@208 | 173 | |
aoqi@208 | 174 | /* |
aoqi@208 | 175 | * "<< 17 >> 23 << 4" is short for "<< 17 >> 17 >> 6 << 4". vAddr = sign_extend(offset << 4 ) + GPR[base] |
aoqi@208 | 176 | * "<< 17 >> 17": sign-extending |
aoqi@208 | 177 | * ">> 6": offset pos |
aoqi@208 | 178 | * "<< 4": offset << 4 |
aoqi@208 | 179 | */ |
aoqi@208 | 180 | #define PRINT_ORRRI_GSLQ(OP) \ |
aoqi@208 | 181 | env->print("%s %s, %s, %d(%s)", OP, as_Register((insn)&0x1f)->name(), \ |
aoqi@208 | 182 | as_Register(Assembler::rt(insn))->name(), (Assembler::low(insn, 15) << 17 >> 23 << 4), \ |
aoqi@208 | 183 | as_Register(Assembler::rs(insn))->name()) |
aoqi@208 | 184 | |
aoqi@208 | 185 | #define PRINT_ORRR_2(OP) \ |
aoqi@208 | 186 | env->print("%s %s, %s, %s", OP, as_Register(Assembler::rd(insn))->name(), \ |
aoqi@208 | 187 | as_Register(Assembler::rt(insn))->name(), \ |
aoqi@208 | 188 | as_Register(Assembler::rs(insn))->name() ) |
aoqi@208 | 189 | |
aoqi@208 | 190 | #define PRINT_ORS(OP) \ |
aoqi@208 | 191 | env->print("%s %s", OP, as_Register(Assembler::rs(insn))->name()) |
aoqi@208 | 192 | |
aoqi@208 | 193 | #define PRINT_ORD(OP) \ |
aoqi@208 | 194 | env->print("%s %s", OP, as_Register(Assembler::rd(insn))->name()) |
aoqi@208 | 195 | |
aoqi@208 | 196 | #define PRINT_ORR(OP) \ |
aoqi@208 | 197 | env->print("%s %s, %s", OP, as_Register(Assembler::rs(insn))->name(), \ |
aoqi@208 | 198 | as_Register(Assembler::rt(insn))->name()) |
aoqi@208 | 199 | |
aoqi@208 | 200 | #define PRINT_ORR_2(OP) \ |
aoqi@208 | 201 | env->print("%s %s, %s", OP, as_Register(Assembler::rt(insn))->name(), \ |
aoqi@208 | 202 | as_Register(Assembler::rd(insn))->name()) |
aoqi@208 | 203 | |
aoqi@208 | 204 | #define PRINT_FLOAT(OP) \ |
aoqi@208 | 205 | env->print("%s.%s %s, %s, %s", OP, fmt, as_FloatRegister(Assembler::sa(insn))->name(), \ |
aoqi@208 | 206 | as_FloatRegister(Assembler::rd(insn))->name(), \ |
aoqi@208 | 207 | as_FloatRegister(Assembler::rt(insn))->name() ) |
aoqi@208 | 208 | |
aoqi@208 | 209 | #define PRINT_CVT(OP) \ |
aoqi@208 | 210 | env->print("%s.%s %s, %s", OP, fmt, as_FloatRegister(Assembler::sa(insn))->name(), \ |
aoqi@208 | 211 | as_FloatRegister(Assembler::rd(insn))->name() ) |
aoqi@208 | 212 | |
aoqi@339 | 213 | #define PRINT_C_COND_FMT(OP) \ |
aoqi@339 | 214 | env->print("%s.%s $fcc%d, %s, %s", OP, fmt, fcc, as_FloatRegister(Assembler::rt(insn))->name(), \ |
aoqi@339 | 215 | as_FloatRegister(Assembler::rd(insn))->name()) |
aoqi@339 | 216 | |
aoqi@208 | 217 | static const char* fmt_str(int fmt) { |
aoqi@208 | 218 | switch(fmt) { |
aoqi@208 | 219 | case Assembler::single_fmt: |
aoqi@208 | 220 | return "s"; |
aoqi@208 | 221 | case Assembler::double_fmt: |
aoqi@208 | 222 | return "d"; |
aoqi@208 | 223 | case Assembler::word_fmt: |
aoqi@208 | 224 | return "w"; |
aoqi@208 | 225 | case Assembler::long_fmt: |
aoqi@208 | 226 | return "l"; |
aoqi@365 | 227 | case Assembler::ps_fmt: |
aoqi@365 | 228 | return "ps"; |
aoqi@208 | 229 | } |
aoqi@208 | 230 | |
aoqi@208 | 231 | return ""; |
aoqi@208 | 232 | } |
aoqi@208 | 233 | |
aoqi@208 | 234 | address Disassembler::decode_instruction(address start, DisassemblerEnv* env) { |
aoqi@208 | 235 | int insn = *(int*)start; |
aoqi@208 | 236 | int opcode = Assembler::opcode(insn); |
aoqi@208 | 237 | int special; |
aoqi@208 | 238 | const char *fmt; |
aoqi@339 | 239 | int flag = 0; |
aoqi@339 | 240 | int fcc = 0; |
aoqi@208 | 241 | |
aoqi@208 | 242 | if (insn == 0) |
aoqi@208 | 243 | { |
aoqi@208 | 244 | PRINT_NOP(); |
aoqi@208 | 245 | return start+4; |
aoqi@208 | 246 | } |
aoqi@208 | 247 | |
aoqi@208 | 248 | switch(opcode) { |
aoqi@208 | 249 | // case op |
aoqi@208 | 250 | // case special_op |
aoqi@208 | 251 | // case regimm_op |
aoqi@208 | 252 | // case cop0_op not |
aoqi@208 | 253 | // case cop1_op |
aoqi@208 | 254 | // case cop2_op not |
aoqi@208 | 255 | // case cop1x_op |
aoqi@208 | 256 | // case special2_op |
aoqi@208 | 257 | // case special3_op |
aoqi@208 | 258 | // case gs_lwc2_op |
aoqi@208 | 259 | // case gs_ldc2_op |
aoqi@208 | 260 | // case gs_swc2_op |
aoqi@208 | 261 | // case gs_sdc2_op |
aoqi@208 | 262 | case Assembler::j_op: |
aoqi@208 | 263 | case Assembler::jal_op: |
aoqi@208 | 264 | PRINT_J(Assembler::ops_name[opcode]); |
aoqi@208 | 265 | break; |
aoqi@208 | 266 | case Assembler::beq_op: |
aoqi@208 | 267 | case Assembler::bne_op: |
aoqi@208 | 268 | case Assembler::blez_op: |
aoqi@208 | 269 | case Assembler::bgtz_op: |
aoqi@208 | 270 | PRINT_ORRL(Assembler::ops_name[opcode]); |
aoqi@208 | 271 | break; |
aoqi@208 | 272 | case Assembler::addi_op: |
aoqi@208 | 273 | case Assembler::addiu_op: |
aoqi@208 | 274 | case Assembler::slti_op: |
aoqi@208 | 275 | case Assembler::sltiu_op: |
aoqi@208 | 276 | case Assembler::ori_op: |
aoqi@208 | 277 | case Assembler::andi_op: |
aoqi@208 | 278 | case Assembler::xori_op: |
aoqi@208 | 279 | case Assembler::daddi_op: |
aoqi@208 | 280 | case Assembler::daddiu_op: |
aoqi@208 | 281 | PRINT_ORRI(Assembler::ops_name[opcode]); |
aoqi@208 | 282 | break; |
aoqi@208 | 283 | case Assembler::lui_op: |
aoqi@208 | 284 | env->print("lui %s, 0x%x", as_Register(Assembler::rt(insn))->name(), (short)Assembler::low16(insn) ); \ |
aoqi@208 | 285 | break; |
aoqi@208 | 286 | case Assembler::beql_op: |
aoqi@208 | 287 | case Assembler::bnel_op: |
aoqi@208 | 288 | case Assembler::blezl_op: |
aoqi@208 | 289 | case Assembler::bgtzl_op: |
aoqi@208 | 290 | PRINT_ORRL(Assembler::ops_name[opcode]); |
aoqi@208 | 291 | break; |
aoqi@208 | 292 | case Assembler::ldl_op: |
aoqi@208 | 293 | case Assembler::ldr_op: |
aoqi@208 | 294 | case Assembler::lb_op: |
aoqi@208 | 295 | case Assembler::lh_op: |
aoqi@208 | 296 | case Assembler::lwl_op: |
aoqi@208 | 297 | case Assembler::lw_op: |
aoqi@208 | 298 | case Assembler::lbu_op: |
aoqi@208 | 299 | case Assembler::lhu_op: |
aoqi@208 | 300 | case Assembler::lwr_op: |
aoqi@208 | 301 | case Assembler::lwu_op: |
aoqi@208 | 302 | case Assembler::sb_op: |
aoqi@208 | 303 | case Assembler::sh_op: |
aoqi@208 | 304 | case Assembler::swl_op: |
aoqi@208 | 305 | case Assembler::sw_op: |
aoqi@208 | 306 | case Assembler::sdl_op: |
aoqi@208 | 307 | case Assembler::sdr_op: |
aoqi@208 | 308 | case Assembler::swr_op: |
aoqi@208 | 309 | case Assembler::ll_op: |
aoqi@208 | 310 | case Assembler::lld_op: |
aoqi@208 | 311 | case Assembler::ld_op: |
aoqi@208 | 312 | case Assembler::sc_op: |
aoqi@208 | 313 | case Assembler::scd_op: |
aoqi@208 | 314 | case Assembler::sd_op: |
aoqi@208 | 315 | PRINT_OROB(Assembler::ops_name[opcode]); |
aoqi@208 | 316 | break; |
aoqi@208 | 317 | case Assembler::sdc1_op: |
aoqi@208 | 318 | case Assembler::ldc1_op: |
aoqi@208 | 319 | case Assembler::lwc1_op: |
aoqi@208 | 320 | case Assembler::swc1_op: |
aoqi@208 | 321 | PRINT_OFOB(Assembler::ops_name[opcode]); |
aoqi@208 | 322 | break; |
aoqi@208 | 323 | |
aoqi@208 | 324 | case Assembler::special_op: { |
aoqi@208 | 325 | special = Assembler::special(insn); |
aoqi@208 | 326 | switch(special) { |
aoqi@208 | 327 | case Assembler::sll_op: |
fujie@315 | 328 | PRINT_ORRS(Assembler::special_name[special]); |
fujie@315 | 329 | break; |
aoqi@208 | 330 | case Assembler::srl_op: |
fujie@315 | 331 | if (insn & (1 << 21)) { |
fujie@315 | 332 | PRINT_ORRS("rotr"); |
fujie@315 | 333 | } else { |
fujie@315 | 334 | PRINT_ORRS(Assembler::special_name[special]); |
fujie@315 | 335 | } |
fujie@315 | 336 | break; |
aoqi@208 | 337 | case Assembler::sra_op: |
fujie@315 | 338 | PRINT_ORRS(Assembler::special_name[special]); |
fujie@315 | 339 | break; |
aoqi@208 | 340 | case Assembler::dsll_op: |
fujie@315 | 341 | PRINT_ORRS(Assembler::special_name[special]); |
fujie@315 | 342 | break; |
aoqi@208 | 343 | case Assembler::dsrl_op: |
fujie@315 | 344 | if (insn & (1 << 21)) { |
fujie@315 | 345 | PRINT_ORRS("drotr"); |
fujie@315 | 346 | } else { |
fujie@315 | 347 | PRINT_ORRS(Assembler::special_name[special]); |
fujie@315 | 348 | } |
fujie@315 | 349 | break; |
aoqi@208 | 350 | case Assembler::dsra_op: |
fujie@315 | 351 | PRINT_ORRS(Assembler::special_name[special]); |
fujie@315 | 352 | break; |
aoqi@208 | 353 | case Assembler::dsll32_op: |
fujie@315 | 354 | PRINT_ORRS(Assembler::special_name[special]); |
fujie@315 | 355 | break; |
aoqi@208 | 356 | case Assembler::dsrl32_op: |
fujie@315 | 357 | if (insn & (1 << 21)) { |
fujie@315 | 358 | PRINT_ORRS("drotr32"); |
fujie@315 | 359 | } else { |
fujie@315 | 360 | PRINT_ORRS(Assembler::special_name[special]); |
fujie@315 | 361 | } |
fujie@315 | 362 | break; |
aoqi@208 | 363 | case Assembler::dsra32_op: |
aoqi@208 | 364 | PRINT_ORRS(Assembler::special_name[special]); |
aoqi@208 | 365 | break; |
aoqi@208 | 366 | |
aoqi@208 | 367 | case Assembler::movci_op: |
aoqi@208 | 368 | flag = insn & (1 << 16); |
aoqi@208 | 369 | if (flag) { |
aoqi@208 | 370 | env->print("movt %s, %s", as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rs(insn))->name()); |
aoqi@208 | 371 | } else { |
aoqi@208 | 372 | env->print("movf %s, %s", as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rs(insn))->name()); |
aoqi@208 | 373 | } |
aoqi@208 | 374 | break; |
aoqi@208 | 375 | |
aoqi@208 | 376 | case Assembler::sllv_op: |
fujie@315 | 377 | PRINT_ORRR_2(Assembler::special_name[special]); |
fujie@315 | 378 | break; |
aoqi@208 | 379 | case Assembler::srlv_op: |
fujie@315 | 380 | if (insn & (1 << 6)) { |
fujie@315 | 381 | PRINT_ORRR_2("rotrv"); |
fujie@315 | 382 | } else { |
fujie@315 | 383 | PRINT_ORRR_2(Assembler::special_name[special]); |
fujie@315 | 384 | } |
fujie@315 | 385 | break; |
aoqi@208 | 386 | case Assembler::srav_op: |
fujie@315 | 387 | PRINT_ORRR_2(Assembler::special_name[special]); |
fujie@315 | 388 | break; |
aoqi@208 | 389 | case Assembler::dsllv_op: |
fujie@315 | 390 | PRINT_ORRR_2(Assembler::special_name[special]); |
fujie@315 | 391 | break; |
aoqi@208 | 392 | case Assembler::dsrlv_op: |
fujie@315 | 393 | if (insn & (1 << 6)) { |
fujie@315 | 394 | PRINT_ORRR_2("drotrv"); |
fujie@315 | 395 | } else { |
fujie@315 | 396 | PRINT_ORRR_2(Assembler::special_name[special]); |
fujie@315 | 397 | } |
fujie@315 | 398 | break; |
aoqi@208 | 399 | case Assembler::dsrav_op: |
aoqi@208 | 400 | PRINT_ORRR_2(Assembler::special_name[special]); |
aoqi@208 | 401 | break; |
aoqi@208 | 402 | |
aoqi@208 | 403 | case Assembler::jr_op: |
aoqi@208 | 404 | case Assembler::jalr_op: |
aoqi@208 | 405 | case Assembler::mthi_op: |
aoqi@208 | 406 | case Assembler::mtlo_op: |
aoqi@208 | 407 | PRINT_ORS(Assembler::special_name[special]); |
aoqi@208 | 408 | break; |
aoqi@208 | 409 | |
aoqi@208 | 410 | case Assembler::syscall_op: |
aoqi@208 | 411 | case Assembler::break_op: |
aoqi@208 | 412 | env->print("%s 0x%x\n", Assembler::special_name[special], bitfield(insn, 6, 20)>>10); |
aoqi@208 | 413 | break; |
aoqi@208 | 414 | |
aoqi@208 | 415 | case Assembler::sync_op: |
aoqi@208 | 416 | env->print("sync\n"); |
aoqi@208 | 417 | break; |
aoqi@208 | 418 | |
aoqi@208 | 419 | case Assembler::mfhi_op: |
aoqi@208 | 420 | case Assembler::mflo_op: |
aoqi@208 | 421 | PRINT_ORD(Assembler::special_name[special]); |
aoqi@208 | 422 | break; |
aoqi@208 | 423 | |
aoqi@208 | 424 | case Assembler::mult_op: |
aoqi@208 | 425 | case Assembler::multu_op: |
aoqi@208 | 426 | case Assembler::div_op: |
aoqi@208 | 427 | case Assembler::divu_op: |
aoqi@208 | 428 | case Assembler::dmult_op: |
aoqi@208 | 429 | case Assembler::dmultu_op: |
aoqi@208 | 430 | case Assembler::ddiv_op: |
aoqi@208 | 431 | case Assembler::ddivu_op: |
aoqi@208 | 432 | PRINT_ORR(Assembler::special_name[special]); |
aoqi@208 | 433 | break; |
aoqi@208 | 434 | |
aoqi@208 | 435 | case Assembler::add_op: |
aoqi@208 | 436 | case Assembler::addu_op: |
aoqi@208 | 437 | case Assembler::sub_op: |
aoqi@208 | 438 | case Assembler::subu_op: |
aoqi@208 | 439 | case Assembler::and_op: |
aoqi@208 | 440 | case Assembler::or_op: |
aoqi@208 | 441 | case Assembler::xor_op: |
aoqi@208 | 442 | case Assembler::nor_op: |
aoqi@208 | 443 | case Assembler::slt_op: |
aoqi@208 | 444 | case Assembler::sltu_op: |
aoqi@208 | 445 | case Assembler::movz_op: |
aoqi@208 | 446 | case Assembler::movn_op: |
aoqi@208 | 447 | case Assembler::dadd_op: |
aoqi@208 | 448 | case Assembler::daddu_op: |
aoqi@208 | 449 | case Assembler::dsub_op: |
aoqi@208 | 450 | case Assembler::dsubu_op: |
aoqi@208 | 451 | PRINT_ORRR(Assembler::special_name[special]); |
aoqi@208 | 452 | break; |
aoqi@208 | 453 | |
aoqi@208 | 454 | case Assembler::tge_op: |
aoqi@208 | 455 | case Assembler::tgeu_op: |
aoqi@208 | 456 | case Assembler::tlt_op: |
aoqi@208 | 457 | case Assembler::tltu_op: |
aoqi@208 | 458 | case Assembler::teq_op: |
aoqi@208 | 459 | case Assembler::tne_op: |
aoqi@208 | 460 | env->print("%s 0x%x, %s, %s\n", Assembler::special_name[special], bitfield(insn, 6, 10), |
aoqi@208 | 461 | as_Register(Assembler::rs(insn))->name(), |
aoqi@208 | 462 | as_Register(Assembler::rt(insn))->name() ); |
aoqi@208 | 463 | break; |
aoqi@208 | 464 | |
aoqi@208 | 465 | default: |
aoqi@208 | 466 | //Unimplemented(); |
aoqi@208 | 467 | env->print("0x%x\n", insn); |
aoqi@208 | 468 | } |
aoqi@208 | 469 | break; |
aoqi@208 | 470 | } //special_op |
aoqi@208 | 471 | |
aoqi@208 | 472 | case Assembler::regimm_op: { |
aoqi@208 | 473 | special = Assembler::rt(insn); |
aoqi@208 | 474 | switch(special) { |
aoqi@208 | 475 | case Assembler::bltz_op: |
aoqi@208 | 476 | case Assembler::bgez_op: |
aoqi@208 | 477 | case Assembler::bltzl_op: |
aoqi@208 | 478 | case Assembler::bgezl_op: |
aoqi@208 | 479 | case Assembler::bltzal_op: |
aoqi@208 | 480 | case Assembler::bgezal_op: |
aoqi@208 | 481 | case Assembler::bltzall_op: |
aoqi@208 | 482 | case Assembler::bgezall_op: |
aoqi@208 | 483 | env->print("[%lx]%s %s, ", *(int *)start, Assembler::regimm_name[special], as_Register(Assembler::rs(insn))->name()); |
aoqi@208 | 484 | env->print_label( (intptr_t)start + 4 + 4 * (short)Assembler::low16(insn) ); |
aoqi@208 | 485 | break; |
aoqi@208 | 486 | |
aoqi@208 | 487 | case Assembler::tgei_op: |
aoqi@208 | 488 | case Assembler::tgeiu_op: |
aoqi@208 | 489 | case Assembler::tlti_op: |
aoqi@208 | 490 | case Assembler::tltiu_op: |
aoqi@208 | 491 | case Assembler::teqi_op: |
aoqi@208 | 492 | case Assembler::tnei_op: |
aoqi@208 | 493 | env->print("%s %s, %d\n", Assembler::regimm_name[special], |
aoqi@208 | 494 | as_Register(Assembler::rs(insn))->name(), |
aoqi@208 | 495 | (short)Assembler::low16(insn)); |
aoqi@208 | 496 | break; |
aoqi@208 | 497 | |
aoqi@208 | 498 | default: |
aoqi@208 | 499 | //Unimplemented(); |
aoqi@208 | 500 | env->print("0x%x\n", insn); |
aoqi@208 | 501 | } |
aoqi@208 | 502 | break; |
aoqi@208 | 503 | } //regimm_op |
aoqi@208 | 504 | |
aoqi@208 | 505 | case Assembler::cop0_op: { |
aoqi@208 | 506 | //Unimplemented(); |
aoqi@208 | 507 | break; |
aoqi@208 | 508 | } //cop0_op |
aoqi@208 | 509 | |
aoqi@208 | 510 | case Assembler::cop1_op: { |
aoqi@208 | 511 | special = Assembler::rs(insn); |
aoqi@208 | 512 | switch(special) { |
aoqi@208 | 513 | case Assembler::mfc1_op: |
aoqi@339 | 514 | env->print("mfc1 %s, %s", as_Register(Assembler::rt(insn))->name(), as_FloatRegister(Assembler::rd(insn))->name()); |
aoqi@208 | 515 | break; |
aoqi@208 | 516 | case Assembler::mtc1_op: |
aoqi@339 | 517 | env->print("mtc1 %s, %s", as_Register(Assembler::rt(insn))->name(), as_FloatRegister(Assembler::rd(insn))->name()); |
aoqi@208 | 518 | break; |
aoqi@208 | 519 | case Assembler::cfc1_op: |
aoqi@208 | 520 | PRINT_ORR_2("cfc1"); |
aoqi@208 | 521 | break; |
aoqi@208 | 522 | case Assembler::ctc1_op: |
aoqi@208 | 523 | PRINT_ORR_2("ctc1"); |
aoqi@208 | 524 | break; |
aoqi@208 | 525 | case Assembler::dmfc1_op: |
aoqi@339 | 526 | env->print("dmfc1 %s, %s", as_Register(Assembler::rt(insn))->name(), as_FloatRegister(Assembler::rd(insn))->name()); |
aoqi@208 | 527 | break; |
aoqi@208 | 528 | case Assembler::dmtc1_op: |
aoqi@208 | 529 | PRINT_ORR_2("dmtc1"); |
aoqi@339 | 530 | env->print("dmtc1 %s, %s", as_Register(Assembler::rt(insn))->name(), as_FloatRegister(Assembler::rd(insn))->name()); |
aoqi@208 | 531 | break; |
aoqi@208 | 532 | |
aoqi@208 | 533 | case Assembler::bc1f_op: |
aoqi@208 | 534 | special = Assembler::rt(insn); |
aoqi@339 | 535 | fcc = (special >> 2) & 0x7; |
aoqi@339 | 536 | special = special & 0x3; |
aoqi@208 | 537 | switch(special) { |
aoqi@208 | 538 | case Assembler::bcf_op: |
aoqi@339 | 539 | env->print("bc1f $fcc%d ", fcc); |
aoqi@208 | 540 | env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) ); |
aoqi@339 | 541 | //env->print("\n"); |
aoqi@208 | 542 | break; |
aoqi@208 | 543 | case Assembler::bcfl_op: |
aoqi@339 | 544 | env->print("bc1fl $fcc%d ", fcc); |
aoqi@208 | 545 | env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) ); |
aoqi@339 | 546 | //env->print("\n"); |
aoqi@208 | 547 | break; |
aoqi@208 | 548 | case Assembler::bct_op: |
aoqi@339 | 549 | env->print("bc1t $fcc%d ", fcc); |
aoqi@208 | 550 | env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) ); |
aoqi@339 | 551 | //env->print("\n"); |
aoqi@208 | 552 | break; |
aoqi@208 | 553 | case Assembler::bctl_op: |
aoqi@339 | 554 | env->print("bc1tl $fcc%d ", fcc); |
aoqi@208 | 555 | env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) ); |
aoqi@339 | 556 | //env->print("\n"); |
aoqi@208 | 557 | break; |
aoqi@208 | 558 | default: |
aoqi@208 | 559 | //Unimplemented(); |
aoqi@208 | 560 | env->print("0x%x\n", insn); |
aoqi@208 | 561 | } |
aoqi@208 | 562 | break; |
aoqi@208 | 563 | case Assembler::single_fmt: |
aoqi@208 | 564 | case Assembler::double_fmt: |
aoqi@208 | 565 | case Assembler::word_fmt: |
aoqi@208 | 566 | case Assembler::long_fmt: |
aoqi@339 | 567 | fmt = fmt_str(special); |
aoqi@208 | 568 | special = Assembler::special(insn); |
aoqi@208 | 569 | switch(special) { |
aoqi@208 | 570 | case Assembler::fadd_op: |
aoqi@208 | 571 | case Assembler::fsub_op: |
aoqi@208 | 572 | case Assembler::fmul_op: |
aoqi@208 | 573 | case Assembler::fdiv_op: |
aoqi@208 | 574 | case Assembler::fsqrt_op: |
aoqi@208 | 575 | case Assembler::fabs_op: |
aoqi@208 | 576 | case Assembler::fmov_op: |
aoqi@208 | 577 | case Assembler::fneg_op: |
aoqi@208 | 578 | case Assembler::froundl_op: |
aoqi@208 | 579 | case Assembler::ftruncl_op: |
aoqi@208 | 580 | case Assembler::fceill_op: |
aoqi@208 | 581 | case Assembler::ffloorl_op: |
aoqi@208 | 582 | case Assembler::froundw_op: |
aoqi@208 | 583 | case Assembler::ftruncw_op: |
aoqi@208 | 584 | case Assembler::fceilw_op: |
aoqi@208 | 585 | case Assembler::ffloorw_op: |
aoqi@208 | 586 | PRINT_FLOAT(Assembler::cop1_name[special]); |
aoqi@208 | 587 | break; |
aoqi@208 | 588 | |
aoqi@208 | 589 | case Assembler::fcvts_op: |
aoqi@208 | 590 | PRINT_CVT("cvt.s"); |
aoqi@208 | 591 | break; |
aoqi@208 | 592 | case Assembler::fcvtd_op: |
aoqi@208 | 593 | PRINT_CVT("cvt.d"); |
aoqi@208 | 594 | break; |
aoqi@208 | 595 | case Assembler::fcvtw_op: |
aoqi@208 | 596 | PRINT_CVT("cvt.w"); |
aoqi@208 | 597 | break; |
aoqi@208 | 598 | case Assembler::fcvtl_op: |
aoqi@208 | 599 | PRINT_CVT("cvt.l"); |
aoqi@208 | 600 | break; |
aoqi@365 | 601 | case Assembler::fcvtps_op: |
aoqi@365 | 602 | assert(Assembler::rs(insn) == Assembler::single_fmt, ""); |
aoqi@365 | 603 | env->print("cvt.ps.s %s, %s, %s", as_FloatRegister(Assembler::sa(insn))->name(), as_FloatRegister(Assembler::rd(insn))->name(), as_FloatRegister(Assembler::rt(insn))->name()); |
aoqi@365 | 604 | break; |
aoqi@339 | 605 | case Assembler::f_cond: |
aoqi@339 | 606 | case Assembler::un_cond: |
aoqi@339 | 607 | case Assembler::eq_cond: |
aoqi@339 | 608 | case Assembler::ueq_cond: |
aoqi@339 | 609 | case Assembler::olt_cond: |
aoqi@339 | 610 | case Assembler::ult_cond: |
aoqi@339 | 611 | case Assembler::ole_cond: |
aoqi@339 | 612 | case Assembler::ule_cond: |
aoqi@339 | 613 | case Assembler::sf_cond: |
aoqi@339 | 614 | case Assembler::ngle_cond: |
aoqi@339 | 615 | case Assembler::seq_cond: |
aoqi@339 | 616 | case Assembler::ngl_cond: |
aoqi@339 | 617 | case Assembler::lt_cond: |
aoqi@339 | 618 | case Assembler::nge_cond: |
aoqi@339 | 619 | case Assembler::le_cond: |
aoqi@339 | 620 | case Assembler::ngt_cond: |
aoqi@339 | 621 | fcc = (insn >> 8) & 0x7; |
aoqi@339 | 622 | PRINT_C_COND_FMT(Assembler::cop1_name[special]); |
aoqi@339 | 623 | break; |
aoqi@208 | 624 | default: |
aoqi@208 | 625 | //tty->print_cr("0x%x(%x)", insn, opcode); |
aoqi@208 | 626 | //Unimplemented(); |
aoqi@208 | 627 | env->print("0x%x\n", insn); |
aoqi@208 | 628 | } |
aoqi@365 | 629 | break; |
aoqi@365 | 630 | case Assembler::ps_fmt: |
aoqi@365 | 631 | fmt = fmt_str(special); |
aoqi@365 | 632 | special = Assembler::special(insn); |
aoqi@365 | 633 | switch(special) { |
aoqi@365 | 634 | case Assembler::fadd_op: |
aoqi@365 | 635 | case Assembler::fsub_op: |
aoqi@365 | 636 | case Assembler::fmul_op: |
aoqi@365 | 637 | case Assembler::fabs_op: |
aoqi@365 | 638 | case Assembler::fmov_op: |
aoqi@365 | 639 | case Assembler::fneg_op: |
aoqi@365 | 640 | PRINT_FLOAT(Assembler::cop1_name[special]); |
aoqi@365 | 641 | break; |
aoqi@365 | 642 | default: |
aoqi@365 | 643 | //tty->print_cr("0x%x(%x)", insn, opcode); |
aoqi@365 | 644 | //Unimplemented(); |
aoqi@365 | 645 | env->print("0x%x\n", insn); |
aoqi@365 | 646 | } |
aoqi@208 | 647 | } |
aoqi@208 | 648 | break; |
aoqi@208 | 649 | } //cop1_op |
aoqi@208 | 650 | |
aoqi@208 | 651 | case Assembler::gs_cop2_op: { |
aoqi@208 | 652 | //Unimplemented(); |
aoqi@339 | 653 | env->print("0x%x\n", insn); |
aoqi@208 | 654 | break; |
aoqi@208 | 655 | } //gs_cop2_op |
aoqi@208 | 656 | |
aoqi@208 | 657 | case Assembler::cop1x_op: { |
aoqi@208 | 658 | special = Assembler::special(insn); |
aoqi@208 | 659 | switch(special) { |
aoqi@208 | 660 | case Assembler::madd_s_op: |
aoqi@208 | 661 | case Assembler::madd_d_op: |
aoqi@208 | 662 | case Assembler::madd_ps_op: |
aoqi@208 | 663 | case Assembler::msub_s_op: |
aoqi@208 | 664 | case Assembler::msub_d_op: |
aoqi@208 | 665 | case Assembler::msub_ps_op: |
aoqi@208 | 666 | case Assembler::nmadd_s_op: |
aoqi@208 | 667 | case Assembler::nmadd_d_op: |
aoqi@208 | 668 | case Assembler::nmadd_ps_op: |
aoqi@208 | 669 | case Assembler::nmsub_s_op: |
aoqi@208 | 670 | case Assembler::nmsub_d_op: |
aoqi@208 | 671 | case Assembler::nmsub_ps_op: |
aoqi@208 | 672 | PRINT_COP1X(Assembler::cop1x_name[Assembler::special(insn)]); |
aoqi@208 | 673 | break; |
aoqi@208 | 674 | } |
aoqi@208 | 675 | break; |
aoqi@208 | 676 | } //cop1x_op |
aoqi@208 | 677 | |
aoqi@208 | 678 | case Assembler::special2_op: { |
aoqi@208 | 679 | special = Assembler::special(insn); |
aoqi@208 | 680 | switch(special) { |
aoqi@208 | 681 | case Assembler::mul_op: |
aoqi@208 | 682 | case Assembler::gsdiv_op: |
aoqi@208 | 683 | case Assembler::gsddiv_op: |
aoqi@208 | 684 | case Assembler::gsmod_op: |
aoqi@208 | 685 | case Assembler::gsdmod_op: |
aoqi@208 | 686 | case Assembler::gsdmult_op: |
aoqi@208 | 687 | PRINT_ORRR(Assembler::special2_name[special]); |
aoqi@208 | 688 | break; |
aoqi@208 | 689 | case Assembler::madd_op: |
aoqi@208 | 690 | case Assembler::msub_op: |
aoqi@208 | 691 | PRINT_ORR(Assembler::special2_name[special]); |
aoqi@208 | 692 | break; |
fujie@295 | 693 | case Assembler::gs0x03_op: |
fujie@295 | 694 | if ( (insn & (0x1f << 6)) == (18 << 6) ) { |
fujie@295 | 695 | PRINT_ORR("gsandn"); |
fujie@295 | 696 | } |
fujie@295 | 697 | break; |
fujie@295 | 698 | case Assembler::gs0x06_op: |
fujie@295 | 699 | if ( (insn & (0x1f << 6)) == (18 << 6) ) { |
fujie@295 | 700 | PRINT_ORR("gsorn"); |
fujie@295 | 701 | } |
fujie@295 | 702 | break; |
aoqi@208 | 703 | } |
aoqi@208 | 704 | break; |
aoqi@208 | 705 | } //special2_op |
aoqi@208 | 706 | |
aoqi@208 | 707 | case Assembler::special3_op: { |
aoqi@208 | 708 | special = Assembler::special(insn); |
aoqi@339 | 709 | int msb = (insn>>11) & 0x1f; |
aoqi@339 | 710 | int lsb = (insn>>6) & 0x1f; |
aoqi@208 | 711 | switch(special) { |
fujie@294 | 712 | case Assembler::ext_op: |
chenhaoxuan@335 | 713 | env->print("ext, %s, %s, 0x%x, 0x%x", as_Register(Assembler::rt(insn))->name(), |
aoqi@339 | 714 | as_Register(Assembler::rs(insn))->name(), lsb, msb + 1); |
chenhaoxuan@335 | 715 | break; |
fujie@301 | 716 | case Assembler::dext_op: |
chenhaoxuan@335 | 717 | env->print("dext, %s, %s, 0x%x, 0x%x", as_Register(Assembler::rt(insn))->name(), |
aoqi@339 | 718 | as_Register(Assembler::rs(insn))->name(), lsb, msb + 1); |
chenhaoxuan@335 | 719 | break; |
aoqi@208 | 720 | case Assembler::ins_op: |
chenhaoxuan@335 | 721 | env->print("ins, %s, %s, 0x%x, 0x%x", as_Register(Assembler::rt(insn))->name(), |
aoqi@339 | 722 | as_Register(Assembler::rs(insn))->name(), lsb, msb - lsb + 1); |
chenhaoxuan@335 | 723 | break; |
aoqi@208 | 724 | case Assembler::dinsm_op: |
chenhaoxuan@335 | 725 | env->print("dinsm, %s, %s, 0x%x, 0x%x", as_Register(Assembler::rt(insn))->name(), |
aoqi@339 | 726 | as_Register(Assembler::rs(insn))->name(), lsb, msb - lsb + 33); |
chenhaoxuan@335 | 727 | break; |
aoqi@208 | 728 | case Assembler::dinsu_op: |
chenhaoxuan@335 | 729 | env->print("dinsu, %s, %s, 0x%x, 0x%x", as_Register(Assembler::rt(insn))->name(), |
aoqi@339 | 730 | as_Register(Assembler::rs(insn))->name(), lsb + 32, msb - lsb + 1); |
chenhaoxuan@335 | 731 | break; |
aoqi@208 | 732 | case Assembler::dins_op: |
chenhaoxuan@335 | 733 | env->print("dins, %s, %s, 0x%x, 0x%x", as_Register(Assembler::rt(insn))->name(), |
aoqi@339 | 734 | as_Register(Assembler::rs(insn))->name(), lsb, msb - lsb + 1); |
aoqi@208 | 735 | break; |
aoqi@359 | 736 | case Assembler::re1_op: { |
aoqi@359 | 737 | int dsp = (insn>>6)&0x1f; |
aoqi@359 | 738 | bool op_is_imm = false; |
aoqi@359 | 739 | switch(dsp) { |
aoqi@359 | 740 | case Assembler::repl_qb_op: |
aoqi@359 | 741 | case Assembler::repl_ph_op: |
aoqi@359 | 742 | op_is_imm = true; |
aoqi@359 | 743 | case Assembler::absq_s_qb_op: |
aoqi@359 | 744 | case Assembler::replv_qb_op: |
aoqi@359 | 745 | case Assembler::absq_s_ph_op: |
aoqi@359 | 746 | case Assembler::replv_ph_op: |
aoqi@359 | 747 | case Assembler::absq_s_w_op: |
aoqi@359 | 748 | case Assembler::bitrev_op: { |
aoqi@359 | 749 | const char* dsp_names[] = { |
aoqi@359 | 750 | "", "absq_s.qb", "repl.qb", "replv.qb", "precequ.ph.qbl", "precequ.ph.qbr", "precequ.ph.qbla", "precequ.ph.qbra", |
aoqi@359 | 751 | "", "absq_s.ph", "repl.ph", "replv.ph", "preceq.w.phl", "preceq.w.phr", "", "", |
aoqi@359 | 752 | "", "absq_s.w", "", "", "", "", "", "", |
aoqi@359 | 753 | "", "", "", "bitrev", "preceu.ph.qbl", "preceu.ph.qbr", "preceu.ph.qbla", "preceu.ph.qbra" |
aoqi@359 | 754 | }; |
aoqi@359 | 755 | if (op_is_imm) |
aoqi@359 | 756 | env->print("%s %s, 0x%x", dsp_names[dsp], as_Register(Assembler::rd(insn))->name(), (insn>>16)&0x3ff); |
aoqi@359 | 757 | else |
aoqi@359 | 758 | env->print("%s %s, %s", dsp_names[dsp], as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rt(insn))->name()); |
aoqi@359 | 759 | break; |
aoqi@359 | 760 | } |
aoqi@359 | 761 | default: |
aoqi@359 | 762 | break; |
aoqi@359 | 763 | } |
aoqi@359 | 764 | break; |
aoqi@359 | 765 | } //Assembler::re1_op |
aoqi@359 | 766 | case Assembler::re2_op: { |
aoqi@359 | 767 | int dsp = (insn>>6)&0x1f; |
aoqi@359 | 768 | bool op_is_imm = false; |
aoqi@359 | 769 | switch(dsp) { |
aoqi@359 | 770 | case Assembler::repl_ob_op: |
aoqi@359 | 771 | case Assembler::repl_qh_op: |
aoqi@359 | 772 | op_is_imm = true; |
aoqi@359 | 773 | case Assembler::replv_ob_op: |
aoqi@359 | 774 | case Assembler::absq_s_qh_op: |
aoqi@359 | 775 | case Assembler::replv_qh_op: |
aoqi@359 | 776 | case Assembler::absq_s_pw_op: |
aoqi@359 | 777 | case Assembler::repl_pw_op: |
aoqi@359 | 778 | case Assembler::replv_pw_op: { |
aoqi@359 | 779 | |
aoqi@359 | 780 | const char* dsp_names[] = { |
aoqi@359 | 781 | "", "", "", "", "", "", "", "", |
aoqi@359 | 782 | "", "absq_s.qh", "repl.qh", "replv.qh", "preceq.pw.qhl", "preceq.pw.qhr", "preceq.pw.phla ", "preceq.pw.phra", |
aoqi@359 | 783 | "", "absq_s.pw", "repl.pw", "replv.pw", "preceq.l.pwl", "preceq.l.pwr", "", "", |
aoqi@359 | 784 | "", "", "", "", "preceu.qh.obl", "preceu.qh.obr", "preceu.qh.obla", "preceu.qh.obra" |
aoqi@359 | 785 | }; |
aoqi@359 | 786 | if (op_is_imm) |
aoqi@359 | 787 | env->print("%s %s, 0x%x", dsp_names[dsp], as_Register(Assembler::rd(insn))->name(), (insn>>16)&0x3ff); |
aoqi@359 | 788 | else |
aoqi@359 | 789 | env->print("%s %s, %s", dsp_names[dsp], as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rt(insn))->name()); |
aoqi@359 | 790 | break; |
aoqi@359 | 791 | } |
aoqi@359 | 792 | default: |
aoqi@359 | 793 | break; |
aoqi@359 | 794 | } |
aoqi@359 | 795 | break; |
aoqi@359 | 796 | } //Assembler::re2_op |
fujie@256 | 797 | case Assembler::bshfl_op: |
fujie@256 | 798 | if ( (insn & (0x1f << 6)) == (Assembler::seb_op << 6) ) { |
fujie@256 | 799 | env->print("seb, %s, %s", as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rt(insn))->name()); |
fujie@256 | 800 | } else if ( (insn & (0x1f << 6)) == (Assembler::seh_op << 6) ) { |
fujie@256 | 801 | env->print("seh, %s, %s", as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rt(insn))->name()); |
fujie@256 | 802 | } else { |
fujie@256 | 803 | env->print("Invalid instruction"); |
fujie@256 | 804 | } |
fujie@256 | 805 | break; |
fujie@292 | 806 | } |
aoqi@208 | 807 | break; |
aoqi@208 | 808 | } //special3_op |
aoqi@208 | 809 | |
aoqi@208 | 810 | case Assembler::gs_lwc2_op: { |
aoqi@208 | 811 | if ((Assembler::special(insn) & 0x20) != 0 ) { |
aoqi@208 | 812 | //gslq rq, rt, offset(base) |
aoqi@208 | 813 | if ( (insn & (1 << 15)) == 0) { |
aoqi@208 | 814 | special = Assembler::gslq_op; |
aoqi@208 | 815 | PRINT_ORRRI_GSLQ(Assembler::gs_lwc2_name[special]); |
aoqi@208 | 816 | } else { |
aoqi@208 | 817 | //gsLQC1 |
aoqi@208 | 818 | env->print("gs_lwc2_op 0x%x\n", insn); |
aoqi@208 | 819 | } |
aoqi@208 | 820 | } else { |
aoqi@208 | 821 | env->print("gs_lwc2_op 0x%x\n", insn); |
aoqi@208 | 822 | } |
aoqi@208 | 823 | break; |
aoqi@208 | 824 | } //gs_lwc2_op |
aoqi@208 | 825 | |
aoqi@208 | 826 | case Assembler::gs_ldc2_op: { |
aoqi@208 | 827 | special = Assembler::special(insn) & 0x7; |
aoqi@365 | 828 | bool is_float = false; |
aoqi@365 | 829 | switch(special) { |
aoqi@365 | 830 | case Assembler::gslbx_op: |
aoqi@365 | 831 | case Assembler::gslhx_op: |
aoqi@365 | 832 | case Assembler::gslwx_op: |
aoqi@365 | 833 | case Assembler::gsldx_op: |
aoqi@365 | 834 | PRINT_ORRRI_GSLDC2(Assembler::gs_ldc2_name[special]); |
aoqi@365 | 835 | break; |
aoqi@365 | 836 | case Assembler::gslwxc1_op: |
aoqi@365 | 837 | case Assembler::gsldxc1_op: |
aoqi@365 | 838 | is_float = true; |
aoqi@365 | 839 | PRINT_ORRRI_GSLDC2(Assembler::gs_ldc2_name[special]); |
aoqi@365 | 840 | break; |
aoqi@365 | 841 | default: |
aoqi@365 | 842 | break; |
aoqi@365 | 843 | } |
aoqi@208 | 844 | break; |
aoqi@208 | 845 | } //gs_ldc2_op |
aoqi@208 | 846 | |
aoqi@208 | 847 | case Assembler::gs_swc2_op: { |
aoqi@208 | 848 | if ((Assembler::special(insn) & 0x20) != 0 ) { |
aoqi@208 | 849 | //gssq rq, rt, offset(base) |
aoqi@208 | 850 | if ( (insn & (1 << 15)) == 0) { |
aoqi@208 | 851 | //gsSQ |
aoqi@208 | 852 | special = Assembler::gssq_op; |
aoqi@208 | 853 | PRINT_ORRRI_GSLQ(Assembler::gs_swc2_name[special]); |
aoqi@208 | 854 | } else { |
aoqi@208 | 855 | //gsSQC1 |
aoqi@208 | 856 | env->print("0x%x\n", insn); |
aoqi@208 | 857 | } |
aoqi@208 | 858 | } else { |
aoqi@208 | 859 | env->print("0x%x\n", insn); |
aoqi@208 | 860 | } |
aoqi@208 | 861 | break; |
aoqi@208 | 862 | } //gs_swc2_op |
aoqi@208 | 863 | |
aoqi@208 | 864 | case Assembler::gs_sdc2_op: { |
aoqi@208 | 865 | special = Assembler::special(insn) & 0x7; |
aoqi@365 | 866 | bool is_float = false; |
aoqi@365 | 867 | switch(special) { |
aoqi@365 | 868 | case Assembler::gssbx_op: |
aoqi@365 | 869 | case Assembler::gsshx_op: |
aoqi@365 | 870 | case Assembler::gsswx_op: |
aoqi@365 | 871 | case Assembler::gssdx_op: |
aoqi@365 | 872 | PRINT_ORRRI_GSLDC2(Assembler::gs_sdc2_name[special]); |
aoqi@365 | 873 | break; |
aoqi@365 | 874 | case Assembler::gsswxc1_op: |
aoqi@365 | 875 | case Assembler::gssdxc1_op: |
aoqi@365 | 876 | is_float = true; |
aoqi@365 | 877 | PRINT_ORRRI_GSLDC2(Assembler::gs_sdc2_name[special]); |
aoqi@365 | 878 | break; |
aoqi@365 | 879 | default: |
aoqi@365 | 880 | break; |
aoqi@365 | 881 | } |
aoqi@208 | 882 | break; |
aoqi@208 | 883 | } //gs_sdc2_op |
aoqi@208 | 884 | |
aoqi@208 | 885 | default: |
aoqi@208 | 886 | //tty->print_cr("0x%x(%x)", insn, opcode); |
aoqi@208 | 887 | //Unimplemented(); |
aoqi@208 | 888 | env->print("0x%x\n", insn); |
aoqi@208 | 889 | } |
aoqi@208 | 890 | |
aoqi@208 | 891 | return start+4; |
aoqi@208 | 892 | } |
aoqi@208 | 893 | |
aoqi@208 | 894 | /* |
aoqi@208 | 895 | void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) { |
aoqi@208 | 896 | if (!load_library()) return; |
aoqi@208 | 897 | decode_env env(CodeCache::find_blob_unsafe(start), st, c); |
aoqi@208 | 898 | env.decode_instructions(start, end); |
aoqi@208 | 899 | } |
aoqi@208 | 900 | */ |
aoqi@208 | 901 | |
aoqi@208 | 902 | void Disassembler::decode(CodeBlob* cb, outputStream* st) { |
aoqi@208 | 903 | #ifndef CORE |
aoqi@208 | 904 | st = st ? st : tty; |
aoqi@208 | 905 | st->print_cr("Decoding CodeBlob " INTPTR_FORMAT, cb); |
aoqi@208 | 906 | decode(cb->content_begin(), cb->content_end(), st); |
aoqi@208 | 907 | #endif |
aoqi@208 | 908 | } |
aoqi@208 | 909 | |
aoqi@208 | 910 | |
aoqi@208 | 911 | void Disassembler::decode(u_char* begin, u_char* end, outputStream* st) { |
aoqi@208 | 912 | st = st ? st : tty; |
aoqi@208 | 913 | |
aoqi@208 | 914 | const int show_bytes = false; // for disassembler debugging |
aoqi@208 | 915 | |
aoqi@208 | 916 | mips32_env env(NULL, st); |
aoqi@208 | 917 | unsigned char* p = (unsigned char*) begin; |
aoqi@208 | 918 | CodeBlob* cb = CodeCache::find_blob_unsafe(begin); |
aoqi@208 | 919 | while (p < (unsigned char*) end) { |
aoqi@208 | 920 | if (cb != NULL) { |
aoqi@208 | 921 | cb->print_block_comment(st, (unsigned char*)(p - cb->content_begin())); |
aoqi@208 | 922 | } |
aoqi@208 | 923 | |
aoqi@208 | 924 | unsigned char* p0 = p; |
aoqi@208 | 925 | st->print(" "INTPTR_FORMAT ": ", p); |
aoqi@208 | 926 | p = decode_instruction(p, &env); |
aoqi@208 | 927 | if (show_bytes) { |
aoqi@208 | 928 | st->print("\t\t\t"); |
aoqi@208 | 929 | while (p0 < p) st->print("%x ", *p0++); |
aoqi@208 | 930 | } |
aoqi@208 | 931 | st->cr(); |
aoqi@208 | 932 | } |
aoqi@208 | 933 | } |
aoqi@208 | 934 | |
aoqi@208 | 935 | |
aoqi@208 | 936 | void Disassembler::decode(nmethod* nm, outputStream* st) { |
aoqi@208 | 937 | #ifndef CORE |
aoqi@208 | 938 | st = st ? st : tty; |
aoqi@208 | 939 | |
aoqi@208 | 940 | st->print_cr("Decoding compiled method " INTPTR_FORMAT ":", nm); |
aoqi@208 | 941 | st->print("Code:"); |
aoqi@208 | 942 | st->cr(); |
aoqi@208 | 943 | |
aoqi@208 | 944 | mips32_env env(nm, st); |
fujie@252 | 945 | |
fujie@252 | 946 | // Print constant table. |
fujie@252 | 947 | if (nm->consts_size() > 0) { |
fujie@252 | 948 | nm->print_nmethod_labels(st, nm->consts_begin()); |
fujie@252 | 949 | int offset = 0; |
fujie@252 | 950 | for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) { |
fujie@252 | 951 | if ((offset % 8) == 0) { |
fujie@252 | 952 | st->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT " " PTR64_FORMAT, p, offset, *((int32_t*) p), *((int64_t*) p)); |
fujie@252 | 953 | } else { |
fujie@252 | 954 | st->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT, p, offset, *((int32_t*) p)); |
fujie@252 | 955 | } |
fujie@252 | 956 | } |
fujie@252 | 957 | } |
fujie@252 | 958 | |
aoqi@208 | 959 | #ifdef COMPILER1 |
aoqi@208 | 960 | unsigned char* p = nm->code_begin(); |
aoqi@208 | 961 | #else |
aoqi@208 | 962 | unsigned char* p = nm->content_begin(); |
aoqi@208 | 963 | #endif |
aoqi@208 | 964 | unsigned char* end = nm->content_end(); |
aoqi@208 | 965 | while (p < end) { |
aoqi@208 | 966 | if (p == nm->entry_point()) st->print_cr("[Entry Point]"); |
aoqi@208 | 967 | if (p == nm->verified_entry_point()) st->print_cr("[Verified Entry Point]"); |
aoqi@208 | 968 | if (p == nm->exception_begin()) st->print_cr("[Exception Handler]"); |
aoqi@208 | 969 | if (p == nm->stub_begin()) st->print_cr("[Stub Code]"); |
aoqi@208 | 970 | if (p == nm->consts_begin()) st->print_cr("[Constants]"); |
aoqi@208 | 971 | nm->print_block_comment(st, (unsigned char*)(p - nm->content_begin())); |
aoqi@208 | 972 | unsigned char* p0 = p; |
aoqi@208 | 973 | st->print(" " INTPTR_FORMAT ": ", p); |
aoqi@208 | 974 | p = decode_instruction(p, &env); |
aoqi@208 | 975 | nm->print_code_comment_on(st, 40, p0, p); |
aoqi@208 | 976 | st->cr(); |
aoqi@208 | 977 | // Output pc bucket ticks if we have any |
aoqi@208 | 978 | address bucket_pc = FlatProfiler::bucket_start_for(p); |
aoqi@208 | 979 | if (bucket_pc != NULL && bucket_pc > p0 && bucket_pc <= p) { |
aoqi@208 | 980 | int bucket_count = FlatProfiler::bucket_count_for(bucket_pc); |
aoqi@208 | 981 | tty->print_cr("[%d]", bucket_count); |
aoqi@208 | 982 | } |
aoqi@208 | 983 | } |
aoqi@208 | 984 | #endif |
aoqi@208 | 985 | } |
aoqi@208 | 986 | |
aoqi@208 | 987 |