src/cpu/mips/vm/disassembler_mips.cpp

Sat, 18 Feb 2017 18:25:01 -0500

author
fujie
date
Sat, 18 Feb 2017 18:25:01 -0500
changeset 315
8ac5b6ff8466
parent 301
d585b6706dc2
child 335
e6f2f90635ab
permissions
-rw-r--r--

[Assembler] Add right-rotate instructions for MIPS.

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) \
aoqi@208 126 env->print((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) \
aoqi@208 157 env->print("%s %s, %s, %s, 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@208 163 env->print("%s %s, %s, %s, 0x%x", OP,as_Register(Assembler::rt(insn))->name(), \
aoqi@208 164 as_Register(Assembler::rs(insn))->name(), \
aoqi@208 165 as_Register(Assembler::rd(insn))->name(), \
aoqi@208 166 ((short)Assembler::low(insn, 11) >> 3) )
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@208 213 static const char* fmt_str(int fmt) {
aoqi@208 214 switch(fmt) {
aoqi@208 215 case Assembler::single_fmt:
aoqi@208 216 return "s";
aoqi@208 217 case Assembler::double_fmt:
aoqi@208 218 return "d";
aoqi@208 219 case Assembler::word_fmt:
aoqi@208 220 return "w";
aoqi@208 221 case Assembler::long_fmt:
aoqi@208 222 return "l";
aoqi@208 223 }
aoqi@208 224
aoqi@208 225 return "";
aoqi@208 226 }
aoqi@208 227
aoqi@208 228 address Disassembler::decode_instruction(address start, DisassemblerEnv* env) {
aoqi@208 229 int insn = *(int*)start;
aoqi@208 230 int opcode = Assembler::opcode(insn);
aoqi@208 231 int special;
aoqi@208 232 const char *fmt;
aoqi@208 233 int flag = 0;
aoqi@208 234
aoqi@208 235 if (insn == 0)
aoqi@208 236 {
aoqi@208 237 PRINT_NOP();
aoqi@208 238 return start+4;
aoqi@208 239 }
aoqi@208 240
aoqi@208 241 switch(opcode) {
aoqi@208 242 // case op
aoqi@208 243 // case special_op
aoqi@208 244 // case regimm_op
aoqi@208 245 // case cop0_op not
aoqi@208 246 // case cop1_op
aoqi@208 247 // case cop2_op not
aoqi@208 248 // case cop1x_op
aoqi@208 249 // case special2_op
aoqi@208 250 // case special3_op
aoqi@208 251 // case gs_lwc2_op
aoqi@208 252 // case gs_ldc2_op
aoqi@208 253 // case gs_swc2_op
aoqi@208 254 // case gs_sdc2_op
aoqi@208 255 case Assembler::j_op:
aoqi@208 256 case Assembler::jal_op:
aoqi@208 257 PRINT_J(Assembler::ops_name[opcode]);
aoqi@208 258 break;
aoqi@208 259 case Assembler::beq_op:
aoqi@208 260 case Assembler::bne_op:
aoqi@208 261 case Assembler::blez_op:
aoqi@208 262 case Assembler::bgtz_op:
aoqi@208 263 PRINT_ORRL(Assembler::ops_name[opcode]);
aoqi@208 264 break;
aoqi@208 265 case Assembler::addi_op:
aoqi@208 266 case Assembler::addiu_op:
aoqi@208 267 case Assembler::slti_op:
aoqi@208 268 case Assembler::sltiu_op:
aoqi@208 269 case Assembler::ori_op:
aoqi@208 270 case Assembler::andi_op:
aoqi@208 271 case Assembler::xori_op:
aoqi@208 272 case Assembler::daddi_op:
aoqi@208 273 case Assembler::daddiu_op:
aoqi@208 274 PRINT_ORRI(Assembler::ops_name[opcode]);
aoqi@208 275 break;
aoqi@208 276 case Assembler::lui_op:
aoqi@208 277 env->print("lui %s, 0x%x", as_Register(Assembler::rt(insn))->name(), (short)Assembler::low16(insn) ); \
aoqi@208 278 break;
aoqi@208 279 case Assembler::beql_op:
aoqi@208 280 case Assembler::bnel_op:
aoqi@208 281 case Assembler::blezl_op:
aoqi@208 282 case Assembler::bgtzl_op:
aoqi@208 283 PRINT_ORRL(Assembler::ops_name[opcode]);
aoqi@208 284 break;
aoqi@208 285 case Assembler::ldl_op:
aoqi@208 286 case Assembler::ldr_op:
aoqi@208 287 case Assembler::lb_op:
aoqi@208 288 case Assembler::lh_op:
aoqi@208 289 case Assembler::lwl_op:
aoqi@208 290 case Assembler::lw_op:
aoqi@208 291 case Assembler::lbu_op:
aoqi@208 292 case Assembler::lhu_op:
aoqi@208 293 case Assembler::lwr_op:
aoqi@208 294 case Assembler::lwu_op:
aoqi@208 295 case Assembler::sb_op:
aoqi@208 296 case Assembler::sh_op:
aoqi@208 297 case Assembler::swl_op:
aoqi@208 298 case Assembler::sw_op:
aoqi@208 299 case Assembler::sdl_op:
aoqi@208 300 case Assembler::sdr_op:
aoqi@208 301 case Assembler::swr_op:
aoqi@208 302 case Assembler::ll_op:
aoqi@208 303 case Assembler::lld_op:
aoqi@208 304 case Assembler::ld_op:
aoqi@208 305 case Assembler::sc_op:
aoqi@208 306 case Assembler::scd_op:
aoqi@208 307 case Assembler::sd_op:
aoqi@208 308 PRINT_OROB(Assembler::ops_name[opcode]);
aoqi@208 309 break;
aoqi@208 310 case Assembler::sdc1_op:
aoqi@208 311 case Assembler::ldc1_op:
aoqi@208 312 case Assembler::lwc1_op:
aoqi@208 313 case Assembler::swc1_op:
aoqi@208 314 PRINT_OFOB(Assembler::ops_name[opcode]);
aoqi@208 315 break;
aoqi@208 316
aoqi@208 317 case Assembler::special_op: {
aoqi@208 318 special = Assembler::special(insn);
aoqi@208 319 switch(special) {
aoqi@208 320 case Assembler::sll_op:
fujie@315 321 PRINT_ORRS(Assembler::special_name[special]);
fujie@315 322 break;
aoqi@208 323 case Assembler::srl_op:
fujie@315 324 if (insn & (1 << 21)) {
fujie@315 325 PRINT_ORRS("rotr");
fujie@315 326 } else {
fujie@315 327 PRINT_ORRS(Assembler::special_name[special]);
fujie@315 328 }
fujie@315 329 break;
aoqi@208 330 case Assembler::sra_op:
fujie@315 331 PRINT_ORRS(Assembler::special_name[special]);
fujie@315 332 break;
aoqi@208 333 case Assembler::dsll_op:
fujie@315 334 PRINT_ORRS(Assembler::special_name[special]);
fujie@315 335 break;
aoqi@208 336 case Assembler::dsrl_op:
fujie@315 337 if (insn & (1 << 21)) {
fujie@315 338 PRINT_ORRS("drotr");
fujie@315 339 } else {
fujie@315 340 PRINT_ORRS(Assembler::special_name[special]);
fujie@315 341 }
fujie@315 342 break;
aoqi@208 343 case Assembler::dsra_op:
fujie@315 344 PRINT_ORRS(Assembler::special_name[special]);
fujie@315 345 break;
aoqi@208 346 case Assembler::dsll32_op:
fujie@315 347 PRINT_ORRS(Assembler::special_name[special]);
fujie@315 348 break;
aoqi@208 349 case Assembler::dsrl32_op:
fujie@315 350 if (insn & (1 << 21)) {
fujie@315 351 PRINT_ORRS("drotr32");
fujie@315 352 } else {
fujie@315 353 PRINT_ORRS(Assembler::special_name[special]);
fujie@315 354 }
fujie@315 355 break;
aoqi@208 356 case Assembler::dsra32_op:
aoqi@208 357 PRINT_ORRS(Assembler::special_name[special]);
aoqi@208 358 break;
aoqi@208 359
aoqi@208 360 case Assembler::movci_op:
aoqi@208 361 flag = insn & (1 << 16);
aoqi@208 362 if (flag) {
aoqi@208 363 env->print("movt %s, %s", as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rs(insn))->name());
aoqi@208 364 } else {
aoqi@208 365 env->print("movf %s, %s", as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rs(insn))->name());
aoqi@208 366 }
aoqi@208 367 break;
aoqi@208 368
aoqi@208 369 case Assembler::sllv_op:
fujie@315 370 PRINT_ORRR_2(Assembler::special_name[special]);
fujie@315 371 break;
aoqi@208 372 case Assembler::srlv_op:
fujie@315 373 if (insn & (1 << 6)) {
fujie@315 374 PRINT_ORRR_2("rotrv");
fujie@315 375 } else {
fujie@315 376 PRINT_ORRR_2(Assembler::special_name[special]);
fujie@315 377 }
fujie@315 378 break;
aoqi@208 379 case Assembler::srav_op:
fujie@315 380 PRINT_ORRR_2(Assembler::special_name[special]);
fujie@315 381 break;
aoqi@208 382 case Assembler::dsllv_op:
fujie@315 383 PRINT_ORRR_2(Assembler::special_name[special]);
fujie@315 384 break;
aoqi@208 385 case Assembler::dsrlv_op:
fujie@315 386 if (insn & (1 << 6)) {
fujie@315 387 PRINT_ORRR_2("drotrv");
fujie@315 388 } else {
fujie@315 389 PRINT_ORRR_2(Assembler::special_name[special]);
fujie@315 390 }
fujie@315 391 break;
aoqi@208 392 case Assembler::dsrav_op:
aoqi@208 393 PRINT_ORRR_2(Assembler::special_name[special]);
aoqi@208 394 break;
aoqi@208 395
aoqi@208 396 case Assembler::jr_op:
aoqi@208 397 case Assembler::jalr_op:
aoqi@208 398 case Assembler::mthi_op:
aoqi@208 399 case Assembler::mtlo_op:
aoqi@208 400 PRINT_ORS(Assembler::special_name[special]);
aoqi@208 401 break;
aoqi@208 402
aoqi@208 403 case Assembler::syscall_op:
aoqi@208 404 case Assembler::break_op:
aoqi@208 405 env->print("%s 0x%x\n", Assembler::special_name[special], bitfield(insn, 6, 20)>>10);
aoqi@208 406 break;
aoqi@208 407
aoqi@208 408 case Assembler::sync_op:
aoqi@208 409 env->print("sync\n");
aoqi@208 410 break;
aoqi@208 411
aoqi@208 412 case Assembler::mfhi_op:
aoqi@208 413 case Assembler::mflo_op:
aoqi@208 414 PRINT_ORD(Assembler::special_name[special]);
aoqi@208 415 break;
aoqi@208 416
aoqi@208 417 case Assembler::mult_op:
aoqi@208 418 case Assembler::multu_op:
aoqi@208 419 case Assembler::div_op:
aoqi@208 420 case Assembler::divu_op:
aoqi@208 421 case Assembler::dmult_op:
aoqi@208 422 case Assembler::dmultu_op:
aoqi@208 423 case Assembler::ddiv_op:
aoqi@208 424 case Assembler::ddivu_op:
aoqi@208 425 PRINT_ORR(Assembler::special_name[special]);
aoqi@208 426 break;
aoqi@208 427
aoqi@208 428 case Assembler::add_op:
aoqi@208 429 case Assembler::addu_op:
aoqi@208 430 case Assembler::sub_op:
aoqi@208 431 case Assembler::subu_op:
aoqi@208 432 case Assembler::and_op:
aoqi@208 433 case Assembler::or_op:
aoqi@208 434 case Assembler::xor_op:
aoqi@208 435 case Assembler::nor_op:
aoqi@208 436 case Assembler::slt_op:
aoqi@208 437 case Assembler::sltu_op:
aoqi@208 438 case Assembler::movz_op:
aoqi@208 439 case Assembler::movn_op:
aoqi@208 440 case Assembler::dadd_op:
aoqi@208 441 case Assembler::daddu_op:
aoqi@208 442 case Assembler::dsub_op:
aoqi@208 443 case Assembler::dsubu_op:
aoqi@208 444 PRINT_ORRR(Assembler::special_name[special]);
aoqi@208 445 break;
aoqi@208 446
aoqi@208 447 case Assembler::tge_op:
aoqi@208 448 case Assembler::tgeu_op:
aoqi@208 449 case Assembler::tlt_op:
aoqi@208 450 case Assembler::tltu_op:
aoqi@208 451 case Assembler::teq_op:
aoqi@208 452 case Assembler::tne_op:
aoqi@208 453 env->print("%s 0x%x, %s, %s\n", Assembler::special_name[special], bitfield(insn, 6, 10),
aoqi@208 454 as_Register(Assembler::rs(insn))->name(),
aoqi@208 455 as_Register(Assembler::rt(insn))->name() );
aoqi@208 456 break;
aoqi@208 457
aoqi@208 458 default:
aoqi@208 459 //Unimplemented();
aoqi@208 460 env->print("0x%x\n", insn);
aoqi@208 461 }
aoqi@208 462 break;
aoqi@208 463 } //special_op
aoqi@208 464
aoqi@208 465 case Assembler::regimm_op: {
aoqi@208 466 special = Assembler::rt(insn);
aoqi@208 467 switch(special) {
aoqi@208 468 case Assembler::bltz_op:
aoqi@208 469 case Assembler::bgez_op:
aoqi@208 470 case Assembler::bltzl_op:
aoqi@208 471 case Assembler::bgezl_op:
aoqi@208 472 case Assembler::bltzal_op:
aoqi@208 473 case Assembler::bgezal_op:
aoqi@208 474 case Assembler::bltzall_op:
aoqi@208 475 case Assembler::bgezall_op:
aoqi@208 476 env->print("[%lx]%s %s, ", *(int *)start, Assembler::regimm_name[special], as_Register(Assembler::rs(insn))->name());
aoqi@208 477 env->print_label( (intptr_t)start + 4 + 4 * (short)Assembler::low16(insn) );
aoqi@208 478 env->print("\n");
aoqi@208 479 break;
aoqi@208 480
aoqi@208 481 case Assembler::tgei_op:
aoqi@208 482 case Assembler::tgeiu_op:
aoqi@208 483 case Assembler::tlti_op:
aoqi@208 484 case Assembler::tltiu_op:
aoqi@208 485 case Assembler::teqi_op:
aoqi@208 486 case Assembler::tnei_op:
aoqi@208 487 env->print("%s %s, %d\n", Assembler::regimm_name[special],
aoqi@208 488 as_Register(Assembler::rs(insn))->name(),
aoqi@208 489 (short)Assembler::low16(insn));
aoqi@208 490 break;
aoqi@208 491
aoqi@208 492 default:
aoqi@208 493 //Unimplemented();
aoqi@208 494 env->print("0x%x\n", insn);
aoqi@208 495 }
aoqi@208 496 break;
aoqi@208 497 } //regimm_op
aoqi@208 498
aoqi@208 499 case Assembler::cop0_op: {
aoqi@208 500 //Unimplemented();
aoqi@208 501 break;
aoqi@208 502 } //cop0_op
aoqi@208 503
aoqi@208 504 case Assembler::cop1_op: {
aoqi@208 505 special = Assembler::rs(insn);
aoqi@208 506 switch(special) {
aoqi@208 507 case Assembler::mfc1_op:
aoqi@208 508 PRINT_ORR_2("mfc1");
aoqi@208 509 break;
aoqi@208 510 case Assembler::mtc1_op:
aoqi@208 511 PRINT_ORR_2("mtc1");
aoqi@208 512 break;
aoqi@208 513 case Assembler::cfc1_op:
aoqi@208 514 PRINT_ORR_2("cfc1");
aoqi@208 515 break;
aoqi@208 516 case Assembler::ctc1_op:
aoqi@208 517 PRINT_ORR_2("ctc1");
aoqi@208 518 break;
aoqi@208 519 case Assembler::dmfc1_op:
aoqi@208 520 PRINT_ORR_2("dmfc1");
aoqi@208 521 break;
aoqi@208 522 case Assembler::dmtc1_op:
aoqi@208 523 PRINT_ORR_2("dmtc1");
aoqi@208 524 break;
aoqi@208 525
aoqi@208 526 case Assembler::bc1f_op:
aoqi@208 527 special = Assembler::rt(insn);
aoqi@208 528 switch(special) {
aoqi@208 529 case Assembler::bcf_op:
aoqi@208 530 env->print("bc1f ");
aoqi@208 531 env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) );
aoqi@208 532 env->print("\n");
aoqi@208 533 break;
aoqi@208 534 case Assembler::bcfl_op:
aoqi@208 535 env->print("bc1fl ");
aoqi@208 536 env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) );
aoqi@208 537 env->print("\n");
aoqi@208 538 break;
aoqi@208 539 case Assembler::bct_op:
aoqi@208 540 env->print("bc1t ");
aoqi@208 541 env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) );
aoqi@208 542 env->print("\n");
aoqi@208 543 break;
aoqi@208 544 case Assembler::bctl_op:
aoqi@208 545 env->print("bc1tl ");
aoqi@208 546 env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) );
aoqi@208 547 env->print("\n");
aoqi@208 548 break;
aoqi@208 549 default:
aoqi@208 550 //Unimplemented();
aoqi@208 551 env->print("0x%x\n", insn);
aoqi@208 552 }
aoqi@208 553 break;
aoqi@208 554 case Assembler::single_fmt:
aoqi@208 555 case Assembler::double_fmt:
aoqi@208 556 case Assembler::word_fmt:
aoqi@208 557 case Assembler::long_fmt:
aoqi@208 558 fmt = fmt_str(special);
aoqi@208 559 special = Assembler::special(insn);
aoqi@208 560 switch(special) {
aoqi@208 561 case Assembler::fadd_op:
aoqi@208 562 case Assembler::fsub_op:
aoqi@208 563 case Assembler::fmul_op:
aoqi@208 564 case Assembler::fdiv_op:
aoqi@208 565 case Assembler::fsqrt_op:
aoqi@208 566 case Assembler::fabs_op:
aoqi@208 567 case Assembler::fmov_op:
aoqi@208 568 case Assembler::fneg_op:
aoqi@208 569 case Assembler::froundl_op:
aoqi@208 570 case Assembler::ftruncl_op:
aoqi@208 571 case Assembler::fceill_op:
aoqi@208 572 case Assembler::ffloorl_op:
aoqi@208 573 case Assembler::froundw_op:
aoqi@208 574 case Assembler::ftruncw_op:
aoqi@208 575 case Assembler::fceilw_op:
aoqi@208 576 case Assembler::ffloorw_op:
aoqi@208 577 PRINT_FLOAT(Assembler::cop1_name[special]);
aoqi@208 578 break;
aoqi@208 579
aoqi@208 580 case Assembler::fcvts_op:
aoqi@208 581 PRINT_CVT("cvt.s");
aoqi@208 582 break;
aoqi@208 583 case Assembler::fcvtd_op:
aoqi@208 584 PRINT_CVT("cvt.d");
aoqi@208 585 break;
aoqi@208 586 case Assembler::fcvtw_op:
aoqi@208 587 PRINT_CVT("cvt.w");
aoqi@208 588 break;
aoqi@208 589 case Assembler::fcvtl_op:
aoqi@208 590 PRINT_CVT("cvt.l");
aoqi@208 591 break;
aoqi@208 592 default:
aoqi@208 593 //tty->print_cr("0x%x(%x)", insn, opcode);
aoqi@208 594 //Unimplemented();
aoqi@208 595 env->print("0x%x\n", insn);
aoqi@208 596 }
aoqi@208 597 }
aoqi@208 598 break;
aoqi@208 599 } //cop1_op
aoqi@208 600
aoqi@208 601 case Assembler::gs_cop2_op: {
aoqi@208 602 //Unimplemented();
aoqi@208 603 break;
aoqi@208 604 } //gs_cop2_op
aoqi@208 605
aoqi@208 606 case Assembler::cop1x_op: {
aoqi@208 607 special = Assembler::special(insn);
aoqi@208 608 switch(special) {
aoqi@208 609 case Assembler::madd_s_op:
aoqi@208 610 case Assembler::madd_d_op:
aoqi@208 611 case Assembler::madd_ps_op:
aoqi@208 612 case Assembler::msub_s_op:
aoqi@208 613 case Assembler::msub_d_op:
aoqi@208 614 case Assembler::msub_ps_op:
aoqi@208 615 case Assembler::nmadd_s_op:
aoqi@208 616 case Assembler::nmadd_d_op:
aoqi@208 617 case Assembler::nmadd_ps_op:
aoqi@208 618 case Assembler::nmsub_s_op:
aoqi@208 619 case Assembler::nmsub_d_op:
aoqi@208 620 case Assembler::nmsub_ps_op:
aoqi@208 621 PRINT_COP1X(Assembler::cop1x_name[Assembler::special(insn)]);
aoqi@208 622 break;
aoqi@208 623 }
aoqi@208 624 break;
aoqi@208 625 } //cop1x_op
aoqi@208 626
aoqi@208 627 case Assembler::special2_op: {
aoqi@208 628 special = Assembler::special(insn);
aoqi@208 629 switch(special) {
aoqi@208 630 case Assembler::mul_op:
aoqi@208 631 case Assembler::gsdiv_op:
aoqi@208 632 case Assembler::gsddiv_op:
aoqi@208 633 case Assembler::gsmod_op:
aoqi@208 634 case Assembler::gsdmod_op:
aoqi@208 635 case Assembler::gsdmult_op:
aoqi@208 636 PRINT_ORRR(Assembler::special2_name[special]);
aoqi@208 637 break;
aoqi@208 638 case Assembler::madd_op:
aoqi@208 639 case Assembler::msub_op:
aoqi@208 640 PRINT_ORR(Assembler::special2_name[special]);
aoqi@208 641 break;
fujie@295 642 case Assembler::gs0x03_op:
fujie@295 643 if ( (insn & (0x1f << 6)) == (18 << 6) ) {
fujie@295 644 PRINT_ORR("gsandn");
fujie@295 645 }
fujie@295 646 break;
fujie@295 647 case Assembler::gs0x06_op:
fujie@295 648 if ( (insn & (0x1f << 6)) == (18 << 6) ) {
fujie@295 649 PRINT_ORR("gsorn");
fujie@295 650 }
fujie@295 651 break;
aoqi@208 652 }
aoqi@208 653 break;
aoqi@208 654 } //special2_op
aoqi@208 655
aoqi@208 656 case Assembler::special3_op: {
aoqi@208 657 special = Assembler::special(insn);
aoqi@208 658 switch(special) {
fujie@294 659 case Assembler::ext_op:
fujie@301 660 case Assembler::dext_op:
aoqi@208 661 case Assembler::ins_op:
aoqi@208 662 case Assembler::dinsm_op:
aoqi@208 663 case Assembler::dinsu_op:
aoqi@208 664 case Assembler::dins_op:
aoqi@208 665 PRINT_ORRII(Assembler::special3_name[special]);
aoqi@208 666 break;
fujie@256 667 case Assembler::bshfl_op:
fujie@256 668 if ( (insn & (0x1f << 6)) == (Assembler::seb_op << 6) ) {
fujie@256 669 env->print("seb, %s, %s", as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rt(insn))->name());
fujie@256 670 } else if ( (insn & (0x1f << 6)) == (Assembler::seh_op << 6) ) {
fujie@256 671 env->print("seh, %s, %s", as_Register(Assembler::rd(insn))->name(), as_Register(Assembler::rt(insn))->name());
fujie@256 672 } else {
fujie@256 673 env->print("Invalid instruction");
fujie@256 674 }
fujie@256 675 break;
fujie@292 676 }
aoqi@208 677 break;
aoqi@208 678 } //special3_op
aoqi@208 679
aoqi@208 680 case Assembler::gs_lwc2_op: {
aoqi@208 681 if ((Assembler::special(insn) & 0x20) != 0 ) {
aoqi@208 682 //gslq rq, rt, offset(base)
aoqi@208 683 if ( (insn & (1 << 15)) == 0) {
aoqi@208 684 special = Assembler::gslq_op;
aoqi@208 685 PRINT_ORRRI_GSLQ(Assembler::gs_lwc2_name[special]);
aoqi@208 686 } else {
aoqi@208 687 //gsLQC1
aoqi@208 688 env->print("gs_lwc2_op 0x%x\n", insn);
aoqi@208 689 }
aoqi@208 690 } else {
aoqi@208 691 env->print("gs_lwc2_op 0x%x\n", insn);
aoqi@208 692 }
aoqi@208 693 break;
aoqi@208 694 } //gs_lwc2_op
aoqi@208 695
aoqi@208 696 case Assembler::gs_ldc2_op: {
aoqi@208 697 special = Assembler::special(insn) & 0x7;
aoqi@208 698 PRINT_ORRRI_GSLDC2(Assembler::gs_ldc2_name[special]);
aoqi@208 699 break;
aoqi@208 700 } //gs_ldc2_op
aoqi@208 701
aoqi@208 702 case Assembler::gs_swc2_op: {
aoqi@208 703 if ((Assembler::special(insn) & 0x20) != 0 ) {
aoqi@208 704 //gssq rq, rt, offset(base)
aoqi@208 705 if ( (insn & (1 << 15)) == 0) {
aoqi@208 706 //gsSQ
aoqi@208 707 special = Assembler::gssq_op;
aoqi@208 708 PRINT_ORRRI_GSLQ(Assembler::gs_swc2_name[special]);
aoqi@208 709 } else {
aoqi@208 710 //gsSQC1
aoqi@208 711 env->print("0x%x\n", insn);
aoqi@208 712 }
aoqi@208 713 } else {
aoqi@208 714 env->print("0x%x\n", insn);
aoqi@208 715 }
aoqi@208 716 break;
aoqi@208 717 } //gs_swc2_op
aoqi@208 718
aoqi@208 719 case Assembler::gs_sdc2_op: {
aoqi@208 720 special = Assembler::special(insn) & 0x7;
aoqi@208 721 PRINT_ORRRI_GSLDC2(Assembler::gs_sdc2_name[special]);
aoqi@208 722 break;
aoqi@208 723 } //gs_sdc2_op
aoqi@208 724
aoqi@208 725 default:
aoqi@208 726 //tty->print_cr("0x%x(%x)", insn, opcode);
aoqi@208 727 //Unimplemented();
aoqi@208 728 env->print("0x%x\n", insn);
aoqi@208 729 }
aoqi@208 730
aoqi@208 731 return start+4;
aoqi@208 732 }
aoqi@208 733
aoqi@208 734 /*
aoqi@208 735 void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) {
aoqi@208 736 if (!load_library()) return;
aoqi@208 737 decode_env env(CodeCache::find_blob_unsafe(start), st, c);
aoqi@208 738 env.decode_instructions(start, end);
aoqi@208 739 }
aoqi@208 740 */
aoqi@208 741
aoqi@208 742 void Disassembler::decode(CodeBlob* cb, outputStream* st) {
aoqi@208 743 #ifndef CORE
aoqi@208 744 st = st ? st : tty;
aoqi@208 745 st->print_cr("Decoding CodeBlob " INTPTR_FORMAT, cb);
aoqi@208 746 decode(cb->content_begin(), cb->content_end(), st);
aoqi@208 747 #endif
aoqi@208 748 }
aoqi@208 749
aoqi@208 750
aoqi@208 751 void Disassembler::decode(u_char* begin, u_char* end, outputStream* st) {
aoqi@208 752 st = st ? st : tty;
aoqi@208 753
aoqi@208 754 const int show_bytes = false; // for disassembler debugging
aoqi@208 755
aoqi@208 756 mips32_env env(NULL, st);
aoqi@208 757 unsigned char* p = (unsigned char*) begin;
aoqi@208 758 CodeBlob* cb = CodeCache::find_blob_unsafe(begin);
aoqi@208 759 while (p < (unsigned char*) end) {
aoqi@208 760 if (cb != NULL) {
aoqi@208 761 cb->print_block_comment(st, (unsigned char*)(p - cb->content_begin()));
aoqi@208 762 }
aoqi@208 763
aoqi@208 764 unsigned char* p0 = p;
aoqi@208 765 st->print(" "INTPTR_FORMAT ": ", p);
aoqi@208 766 p = decode_instruction(p, &env);
aoqi@208 767 if (show_bytes) {
aoqi@208 768 st->print("\t\t\t");
aoqi@208 769 while (p0 < p) st->print("%x ", *p0++);
aoqi@208 770 }
aoqi@208 771 st->cr();
aoqi@208 772 }
aoqi@208 773 }
aoqi@208 774
aoqi@208 775
aoqi@208 776 void Disassembler::decode(nmethod* nm, outputStream* st) {
aoqi@208 777 #ifndef CORE
aoqi@208 778 st = st ? st : tty;
aoqi@208 779
aoqi@208 780 st->print_cr("Decoding compiled method " INTPTR_FORMAT ":", nm);
aoqi@208 781 st->print("Code:");
aoqi@208 782 st->cr();
aoqi@208 783
aoqi@208 784 mips32_env env(nm, st);
fujie@252 785
fujie@252 786 // Print constant table.
fujie@252 787 if (nm->consts_size() > 0) {
fujie@252 788 nm->print_nmethod_labels(st, nm->consts_begin());
fujie@252 789 int offset = 0;
fujie@252 790 for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) {
fujie@252 791 if ((offset % 8) == 0) {
fujie@252 792 st->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT " " PTR64_FORMAT, p, offset, *((int32_t*) p), *((int64_t*) p));
fujie@252 793 } else {
fujie@252 794 st->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT, p, offset, *((int32_t*) p));
fujie@252 795 }
fujie@252 796 }
fujie@252 797 }
fujie@252 798
aoqi@208 799 #ifdef COMPILER1
aoqi@208 800 unsigned char* p = nm->code_begin();
aoqi@208 801 #else
aoqi@208 802 unsigned char* p = nm->content_begin();
aoqi@208 803 #endif
aoqi@208 804 unsigned char* end = nm->content_end();
aoqi@208 805 while (p < end) {
aoqi@208 806 if (p == nm->entry_point()) st->print_cr("[Entry Point]");
aoqi@208 807 if (p == nm->verified_entry_point()) st->print_cr("[Verified Entry Point]");
aoqi@208 808 if (p == nm->exception_begin()) st->print_cr("[Exception Handler]");
aoqi@208 809 if (p == nm->stub_begin()) st->print_cr("[Stub Code]");
aoqi@208 810 if (p == nm->consts_begin()) st->print_cr("[Constants]");
aoqi@208 811 nm->print_block_comment(st, (unsigned char*)(p - nm->content_begin()));
aoqi@208 812 unsigned char* p0 = p;
aoqi@208 813 st->print(" " INTPTR_FORMAT ": ", p);
aoqi@208 814 p = decode_instruction(p, &env);
aoqi@208 815 nm->print_code_comment_on(st, 40, p0, p);
aoqi@208 816 st->cr();
aoqi@208 817 // Output pc bucket ticks if we have any
aoqi@208 818 address bucket_pc = FlatProfiler::bucket_start_for(p);
aoqi@208 819 if (bucket_pc != NULL && bucket_pc > p0 && bucket_pc <= p) {
aoqi@208 820 int bucket_count = FlatProfiler::bucket_count_for(bucket_pc);
aoqi@208 821 tty->print_cr("[%d]", bucket_count);
aoqi@208 822 }
aoqi@208 823 }
aoqi@208 824 #endif
aoqi@208 825 }
aoqi@208 826
aoqi@208 827

mercurial