src/cpu/mips/vm/disassembler_mips.cpp

Tue, 26 Jul 2016 11:15:09 +0800

author
fujie
date
Tue, 26 Jul 2016 11:15:09 +0800
changeset 38
f0e26f502a50
parent 11
0691182d36ec
child 41
d885f8d65c58
permissions
-rw-r--r--

Instruction decoding support: add movn and movz in MIPS disassembler.

aoqi@1 1 /*
aoqi@1 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
aoqi@1 3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
aoqi@1 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@1 5 *
aoqi@1 6 * This code is free software; you can redistribute it and/or modify it
aoqi@1 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@1 8 * published by the Free Software Foundation.
aoqi@1 9 *
aoqi@1 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@1 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@1 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@1 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@1 14 * accompanied this code).
aoqi@1 15 *
aoqi@1 16 * You should have received a copy of the GNU General Public License version
aoqi@1 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@1 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@1 19 *
aoqi@1 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@1 21 * or visit www.oracle.com if you need additional information or have any
aoqi@1 22 * questions.
aoqi@1 23 *
aoqi@1 24 */
aoqi@1 25
aoqi@1 26 #ifdef USE_PRAGMA_IDENT_SRC
aoqi@1 27 #pragma ident "@(#)disassembler_mips.cpp 1.35 03/12/23 16:36:14 JVM"
aoqi@1 28 #endif
aoqi@1 29 //by yjl 6/21/2005
aoqi@1 30 //FIXME: ugly code here, it always loads a dll/so to do actually work, and dont work for product
aoqi@1 31 //change it in the future
aoqi@1 32 //1/2, 07 , jerome
aoqi@1 33 # include "precompiled.hpp"
aoqi@1 34 # include "depChecker_mips.hpp"
aoqi@1 35 # include "runtime/fprofiler.hpp"
aoqi@1 36
aoqi@1 37 //CHANGE_ME BY YJL
aoqi@1 38 #ifndef PRODUCT
aoqi@1 39
aoqi@1 40 class mips32_env : public DisassemblerEnv {
aoqi@1 41 private:
aoqi@1 42 nmethod* code;
aoqi@1 43 outputStream* output;
aoqi@1 44 public:
aoqi@1 45 mips32_env(nmethod* rcode, outputStream* routput) {
aoqi@1 46 code = rcode;
aoqi@1 47 output = routput;
aoqi@1 48 }
aoqi@1 49 void print_label(intptr_t value);
aoqi@1 50 void print_raw(char* str) { output->print_raw(str); }
aoqi@1 51 void print(char* format, ...);
aoqi@1 52 char* string_for_offset(intptr_t value);
aoqi@1 53 char* string_for_constant(unsigned char* pc, intptr_t value, int is_decimal);
aoqi@1 54 };
aoqi@1 55
aoqi@1 56
aoqi@1 57 void mips32_env::print_label(intptr_t value) {
aoqi@1 58 if (!Universe::is_fully_initialized()) {
aoqi@1 59 output->print(INTPTR_FORMAT, value);
aoqi@1 60 return;
aoqi@1 61 }
aoqi@1 62 address adr = (address) value;
aoqi@1 63 if (StubRoutines::contains(adr)) {
aoqi@1 64 StubCodeDesc* desc = StubCodeDesc::desc_for(adr);
aoqi@1 65 const char * desc_name = "unknown stub";
aoqi@1 66 if (desc != NULL) {
aoqi@1 67 desc_name = desc->name();
aoqi@1 68 }
aoqi@1 69 output->print("Stub::%s", desc_name);
aoqi@1 70 if (WizardMode) output->print(" " INTPTR_FORMAT, value);
aoqi@1 71 } else {
aoqi@1 72 output->print(INTPTR_FORMAT, value);
aoqi@1 73 }
aoqi@1 74 }
aoqi@1 75
aoqi@1 76 void mips32_env::print(char* format, ...) {
aoqi@1 77 va_list ap;
aoqi@1 78 va_start(ap, format);
aoqi@1 79 output->vprint(format, ap);
aoqi@1 80 va_end(ap);
aoqi@1 81 }
aoqi@1 82
aoqi@1 83 char* mips32_env::string_for_offset(intptr_t value) {
aoqi@1 84 stringStream st;
aoqi@1 85 if (!Universe::is_fully_initialized()) {
aoqi@1 86 st.print("%d", value);
aoqi@1 87 return st.as_string();
aoqi@1 88 }
aoqi@1 89 BarrierSet* bs = Universe::heap()->barrier_set();
aoqi@1 90 BarrierSet::Name bsn = bs->kind();
aoqi@1 91
aoqi@1 92 if (bs->kind() == BarrierSet::CardTableModRef && (jbyte*) value == ((CardTableModRefBS*)(bs))->byte_map_base) {
aoqi@1 93 st.print("word_map_base");
aoqi@1 94 } else {
aoqi@1 95 st.print("%d", value);
aoqi@1 96 }
aoqi@1 97 return st.as_string();
aoqi@1 98 }
aoqi@1 99
aoqi@1 100 char* mips32_env::string_for_constant(unsigned char* pc, intptr_t value, int is_decimal) {
aoqi@1 101 stringStream st;
aoqi@1 102 oop obj = NULL;
aoqi@1 103 #ifndef CORE
aoqi@1 104 if (code && (obj = code->embeddedOop_at(pc))!=NULL) {
aoqi@1 105 obj->print_value_on(&st);
aoqi@1 106 } else
aoqi@1 107 #endif
aoqi@1 108 {
aoqi@1 109 if (is_decimal == 1) {
aoqi@1 110 st.print("%d", value);
aoqi@1 111 } else {
aoqi@1 112 st.print("0x%lx", value);
aoqi@1 113 }
aoqi@1 114 }
aoqi@1 115 return st.as_string();
aoqi@1 116 }
aoqi@1 117
aoqi@1 118 #define PRINT_NOP() \
aoqi@1 119 env->print("nop");
aoqi@1 120
aoqi@1 121 #define PRINT_ORRI(OP) \
aoqi@1 122 env->print("%s %s, %s, 0x%x", OP, as_Register(Assembler::rt(insn))->name(), \
aoqi@1 123 as_Register(Assembler::rs(insn))->name(), \
aoqi@1 124 (short)Assembler::low16(insn) )
aoqi@1 125
aoqi@1 126 #define PRINT_ORRL(OP) \
aoqi@1 127 env->print("%s %s, %s, ", OP, as_Register(Assembler::rs(insn))->name(), \
aoqi@1 128 as_Register(Assembler::rt(insn))->name()); \
aoqi@1 129 env->print_label( (intptr_t)start + 4 + ((short)Assembler::low16(insn)<<2) )
aoqi@1 130
aoqi@1 131 #define PRINT_J(OP) \
aoqi@1 132 env->print((char*)OP); \
aoqi@1 133 env->print_label( ( ( (intptr_t)start + 4 ) & 0xc0000000 ) | ( Assembler::low26(insn) << 2 ) ); \
aoqi@1 134 env->print("");
aoqi@1 135
aoqi@1 136 #define PRINT_ORSL(OP) \
aoqi@1 137 env->print("%s %s, ", OP, as_Register(Assembler::rs(insn))->name()); \
aoqi@1 138 env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) ); \
aoqi@1 139 env->print("");
aoqi@1 140
aoqi@1 141 #define PRINT_OROB(OP) \
aoqi@1 142 env->print("%s %s, 0x%x(%s)", OP, as_Register(Assembler::rt(insn))->name(), \
aoqi@1 143 (short)Assembler::low16(insn), \
aoqi@1 144 as_Register(Assembler::rs(insn))->name() )
aoqi@1 145
aoqi@1 146 #define PRINT_OFOB(OP) \
aoqi@1 147 env->print("%s %s, 0x%x(%s)", OP, as_FloatRegister(Assembler::rt(insn))->name(), \
aoqi@1 148 (short)Assembler::low16(insn), \
aoqi@1 149 as_Register(Assembler::rs(insn))->name() )
aoqi@1 150
aoqi@1 151
aoqi@1 152 #define PRINT_ORRS(OP) \
aoqi@1 153 env->print("%s %s, %s, %d", OP, as_Register(Assembler::rd(insn))->name(), \
aoqi@1 154 as_Register(Assembler::rt(insn))->name(), \
aoqi@1 155 Assembler::sa(insn) )
aoqi@1 156
aoqi@1 157 #define PRINT_ORRR(OP) \
aoqi@1 158 env->print("%s %s, %s, %s", OP, as_Register(Assembler::rd(insn))->name(), \
aoqi@1 159 as_Register(Assembler::rs(insn))->name(), \
aoqi@1 160 as_Register(Assembler::rt(insn))->name() )
aoqi@1 161
aoqi@1 162 #define PRINT_ORRR_2(OP) \
aoqi@1 163 env->print("%s %s, %s, %s", OP, as_Register(Assembler::rd(insn))->name(), \
aoqi@1 164 as_Register(Assembler::rt(insn))->name(), \
aoqi@1 165 as_Register(Assembler::rs(insn))->name() )
aoqi@1 166
aoqi@1 167 #define PRINT_ORS(OP) \
aoqi@1 168 env->print("%s %s", OP, as_Register(Assembler::rs(insn))->name())
aoqi@1 169
aoqi@1 170 #define PRINT_ORD(OP) \
aoqi@1 171 env->print("%s %s", OP, as_Register(Assembler::rd(insn))->name())
aoqi@1 172
aoqi@1 173 #define PRINT_ORR(OP) \
aoqi@1 174 env->print("%s %s, %s", OP, as_Register(Assembler::rs(insn))->name(), \
aoqi@1 175 as_Register(Assembler::rt(insn))->name())
aoqi@1 176
aoqi@1 177 #define PRINT_ORR_2(OP) \
aoqi@1 178 env->print("%s %s, %s", OP, as_Register(Assembler::rt(insn))->name(), \
aoqi@1 179 as_Register(Assembler::rd(insn))->name())
aoqi@1 180
aoqi@1 181 #define PRINT_FLOAT(OP) \
aoqi@1 182 env->print("%s.%s %s, %s, %s", OP, fmt, as_FloatRegister(Assembler::sa(insn))->name(), \
aoqi@1 183 as_FloatRegister(Assembler::rd(insn))->name(), \
aoqi@1 184 as_FloatRegister(Assembler::rt(insn))->name() )
aoqi@1 185
aoqi@1 186 #define PRINT_CVT(OP) \
aoqi@1 187 env->print("%s.%s %s, %s", OP, fmt, as_FloatRegister(Assembler::sa(insn))->name(), \
aoqi@1 188 as_FloatRegister(Assembler::rd(insn))->name() )
aoqi@1 189
aoqi@1 190 static const char* fmt_str(int fmt) {
aoqi@1 191 switch(fmt) {
aoqi@1 192 case Assembler::single_fmt:
aoqi@1 193 return "s";
aoqi@1 194 case Assembler::double_fmt:
aoqi@1 195 return "d";
aoqi@1 196 case Assembler::word_fmt:
aoqi@1 197 return "w";
aoqi@1 198 case Assembler::long_fmt:
aoqi@1 199 return "l";
aoqi@1 200 }
aoqi@1 201
aoqi@1 202 return "";
aoqi@1 203 }
aoqi@1 204
aoqi@1 205 address Disassembler::decode_instruction(address start, DisassemblerEnv* env) {
aoqi@1 206 int insn = *(int*)start;
aoqi@1 207 int opcode = Assembler::opcode(insn);
aoqi@1 208 int special;
aoqi@1 209 const char *fmt;
aoqi@1 210
aoqi@1 211 if (insn == 0)
aoqi@1 212 {
aoqi@1 213 PRINT_NOP();
aoqi@1 214 return start+4;
aoqi@1 215 }
aoqi@1 216
aoqi@1 217 switch(opcode) {
aoqi@1 218 case Assembler::special_op:
aoqi@1 219 special = Assembler::special(insn);
aoqi@1 220 switch(special) {
aoqi@1 221 case Assembler::sll_op:
aoqi@1 222 case Assembler::srl_op:
aoqi@1 223 case Assembler::sra_op:
aoqi@1 224 case Assembler::dsll_op:
aoqi@1 225 case Assembler::dsrl_op:
aoqi@1 226 case Assembler::dsra_op:
aoqi@1 227 case Assembler::dsll32_op:
aoqi@1 228 case Assembler::dsrl32_op:
aoqi@1 229 case Assembler::dsra32_op:
aoqi@1 230 PRINT_ORRS(Assembler::special_name[special]);
aoqi@1 231 break;
aoqi@1 232
aoqi@1 233 case Assembler::sllv_op:
aoqi@1 234 case Assembler::srlv_op:
aoqi@1 235 case Assembler::srav_op:
aoqi@1 236 case Assembler::dsllv_op:
aoqi@1 237 case Assembler::dsrlv_op:
aoqi@1 238 case Assembler::dsrav_op:
aoqi@1 239 PRINT_ORRR_2(Assembler::special_name[special]);
aoqi@1 240 break;
aoqi@1 241
aoqi@1 242 case Assembler::jr_op:
aoqi@1 243 case Assembler::jalr_op:
aoqi@1 244 case Assembler::mthi_op:
aoqi@1 245 case Assembler::mtlo_op:
aoqi@1 246 PRINT_ORS(Assembler::special_name[special]);
aoqi@1 247 break;
aoqi@1 248
aoqi@1 249 case Assembler::syscall_op:
aoqi@1 250 case Assembler::break_op:
aoqi@1 251 env->print("%s 0x%x\n", Assembler::special_name[special], bitfield(insn, 6, 20)>>10);
aoqi@1 252 break;
aoqi@1 253
aoqi@1 254 case Assembler::sync_op:
aoqi@1 255 env->print("sync\n");
aoqi@1 256 break;
aoqi@1 257
aoqi@1 258 case Assembler::mfhi_op:
aoqi@1 259 case Assembler::mflo_op:
aoqi@1 260 PRINT_ORD(Assembler::special_name[special]);
aoqi@1 261 break;
aoqi@1 262
aoqi@1 263 case Assembler::mult_op:
aoqi@1 264 case Assembler::multu_op:
aoqi@1 265 case Assembler::div_op:
aoqi@1 266 case Assembler::divu_op:
aoqi@1 267 case Assembler::dmult_op:
aoqi@1 268 case Assembler::dmultu_op:
aoqi@1 269 case Assembler::ddiv_op:
aoqi@1 270 case Assembler::ddivu_op:
aoqi@1 271 PRINT_ORR(Assembler::special_name[special]);
aoqi@1 272 break;
aoqi@1 273
aoqi@1 274 case Assembler::add_op:
aoqi@1 275 case Assembler::addu_op:
aoqi@1 276 case Assembler::sub_op:
aoqi@1 277 case Assembler::subu_op:
aoqi@1 278 case Assembler::and_op:
aoqi@1 279 case Assembler::or_op:
aoqi@1 280 case Assembler::xor_op:
aoqi@1 281 case Assembler::nor_op:
aoqi@1 282 case Assembler::slt_op:
aoqi@1 283 case Assembler::sltu_op:
fujie@38 284 case Assembler::movz_op:
fujie@38 285 case Assembler::movn_op:
aoqi@1 286 case Assembler::dadd_op:
aoqi@1 287 case Assembler::daddu_op:
aoqi@1 288 case Assembler::dsub_op:
aoqi@1 289 case Assembler::dsubu_op:
aoqi@1 290 PRINT_ORRR(Assembler::special_name[special]);
aoqi@1 291 break;
aoqi@1 292
aoqi@1 293 case Assembler::tge_op:
aoqi@1 294 case Assembler::tgeu_op:
aoqi@1 295 case Assembler::tlt_op:
aoqi@1 296 case Assembler::tltu_op:
aoqi@1 297 case Assembler::teq_op:
aoqi@1 298 case Assembler::tne_op:
aoqi@1 299 env->print("%s 0x%x, %s, %s\n", Assembler::special_name[special], bitfield(insn, 6, 10),
aoqi@1 300 as_Register(Assembler::rs(insn))->name(),
aoqi@1 301 as_Register(Assembler::rt(insn))->name() );
aoqi@1 302 break;
aoqi@1 303
aoqi@1 304 default:
aoqi@1 305 //Unimplemented();
aoqi@1 306 env->print("0x%x\n", insn);
aoqi@1 307 }
aoqi@1 308 break;
aoqi@1 309
aoqi@1 310 case Assembler::regimm_op:
aoqi@1 311 special = Assembler::rt(insn);
aoqi@1 312
aoqi@1 313 switch(special) {
aoqi@1 314 case Assembler::bltz_op:
aoqi@1 315 case Assembler::bgez_op:
aoqi@1 316 case Assembler::bltzl_op:
aoqi@1 317 case Assembler::bgezl_op:
aoqi@1 318 case Assembler::bltzal_op:
aoqi@1 319 case Assembler::bgezal_op:
aoqi@1 320 case Assembler::bltzall_op:
aoqi@1 321 case Assembler::bgezall_op:
aoqi@11 322 env->print("[%lx]%s %s, ", *(int *)start, Assembler::regimm_name[special], as_Register(Assembler::rs(insn))->name());
aoqi@1 323 env->print_label( (intptr_t)start + 4 + 4 * (short)Assembler::low16(insn) );
aoqi@1 324 env->print("\n");
aoqi@1 325 break;
aoqi@1 326
aoqi@1 327 case Assembler::tgei_op:
aoqi@1 328 case Assembler::tgeiu_op:
aoqi@1 329 case Assembler::tlti_op:
aoqi@1 330 case Assembler::tltiu_op:
aoqi@1 331 case Assembler::teqi_op:
aoqi@1 332 case Assembler::tnei_op:
aoqi@1 333 env->print("%s %s, %d\n", Assembler::regimm_name[special],
aoqi@1 334 as_Register(Assembler::rs(insn))->name(),
aoqi@1 335 (short)Assembler::low16(insn));
aoqi@1 336 break;
aoqi@1 337
aoqi@1 338 default:
aoqi@1 339 //Unimplemented();
aoqi@1 340 env->print("0x%x\n", insn);
aoqi@1 341 }
aoqi@1 342 break;
aoqi@1 343
aoqi@1 344 case Assembler::j_op:
aoqi@1 345 case Assembler::jal_op:
aoqi@1 346 PRINT_J(Assembler::ops_name[opcode]);
aoqi@1 347 break;
aoqi@1 348
aoqi@1 349 case Assembler::beq_op:
aoqi@1 350 case Assembler::bne_op:
aoqi@1 351 case Assembler::blez_op:
aoqi@1 352 case Assembler::bgtz_op:
aoqi@1 353 PRINT_ORRL(Assembler::ops_name[opcode]);
aoqi@1 354 break;
aoqi@1 355
aoqi@1 356 case Assembler::addi_op:
aoqi@1 357 case Assembler::addiu_op:
aoqi@1 358 case Assembler::slti_op:
aoqi@1 359 case Assembler::sltiu_op:
aoqi@1 360 case Assembler::ori_op:
aoqi@1 361 case Assembler::andi_op:
aoqi@1 362 case Assembler::xori_op:
aoqi@1 363 case Assembler::daddi_op:
aoqi@1 364 case Assembler::daddiu_op:
aoqi@1 365 PRINT_ORRI(Assembler::ops_name[opcode]);
aoqi@1 366 break;
aoqi@1 367
aoqi@1 368 case Assembler::lui_op:
aoqi@1 369 env->print("lui %s, 0x%x", as_Register(Assembler::rt(insn))->name(), (short)Assembler::low16(insn) ); \
aoqi@1 370 break;
aoqi@1 371
aoqi@1 372 case Assembler::cop1_op:
aoqi@1 373 special = Assembler::rs(insn);
aoqi@1 374 switch(special) {
aoqi@1 375 case Assembler::mf_op:
aoqi@1 376 PRINT_ORR_2("mfc1");
aoqi@1 377 break;
aoqi@1 378 case Assembler::mt_op:
aoqi@1 379 PRINT_ORR_2("mtc1");
aoqi@1 380 break;
aoqi@1 381 case Assembler::cf_op:
aoqi@1 382 PRINT_ORR_2("cfc1");
aoqi@1 383 break;
aoqi@1 384 case Assembler::ct_op:
aoqi@1 385 PRINT_ORR_2("ctc1");
aoqi@1 386 break;
aoqi@1 387 case Assembler::dmf_op:
aoqi@1 388 PRINT_ORR_2("dmfc1");
aoqi@1 389 break;
aoqi@1 390 case Assembler::dmt_op:
aoqi@1 391 PRINT_ORR_2("dmtc1");
aoqi@1 392 break;
aoqi@1 393
aoqi@1 394 case Assembler::bc_op:
aoqi@1 395 special = Assembler::rt(insn);
aoqi@1 396 switch(special) {
aoqi@1 397 case Assembler::bcf_op:
aoqi@1 398 env->print("bc1f ");
aoqi@1 399 env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) );
aoqi@1 400 env->print("\n");
aoqi@1 401 break;
aoqi@1 402 case Assembler::bcfl_op:
aoqi@1 403 env->print("bc1fl ");
aoqi@1 404 env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) );
aoqi@1 405 env->print("\n");
aoqi@1 406 break;
aoqi@1 407 case Assembler::bct_op:
aoqi@1 408 env->print("bc1t ");
aoqi@1 409 env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) );
aoqi@1 410 env->print("\n");
aoqi@1 411 break;
aoqi@1 412 case Assembler::bctl_op:
aoqi@1 413 env->print("bc1tl ");
aoqi@1 414 env->print_label( (intptr_t)start + 4 + (short)Assembler::low16(insn) );
aoqi@1 415 env->print("\n");
aoqi@1 416 break;
aoqi@1 417 default:
aoqi@1 418 //Unimplemented();
aoqi@1 419 env->print("0x%x\n", insn);
aoqi@1 420 }
aoqi@1 421 break;
aoqi@1 422 case Assembler::single_fmt:
aoqi@1 423 case Assembler::double_fmt:
aoqi@1 424 case Assembler::word_fmt:
aoqi@1 425 case Assembler::long_fmt:
aoqi@1 426 fmt = fmt_str(special);
aoqi@1 427 special = Assembler::special(insn);
aoqi@1 428 switch(special) {
aoqi@1 429 case Assembler::fadd_op:
aoqi@1 430 case Assembler::fsub_op:
aoqi@1 431 case Assembler::fmul_op:
aoqi@1 432 case Assembler::fdiv_op:
aoqi@1 433 case Assembler::fsqrt_op:
aoqi@1 434 case Assembler::fabs_op:
aoqi@1 435 case Assembler::fmov_op:
aoqi@1 436 case Assembler::fneg_op:
aoqi@1 437 case Assembler::froundl_op:
aoqi@1 438 case Assembler::ftruncl_op:
aoqi@1 439 case Assembler::fceill_op:
aoqi@1 440 case Assembler::ffloorl_op:
aoqi@1 441 case Assembler::froundw_op:
aoqi@1 442 case Assembler::ftruncw_op:
aoqi@1 443 case Assembler::fceilw_op:
aoqi@1 444 case Assembler::ffloorw_op:
aoqi@1 445 PRINT_FLOAT(Assembler::float_name[special]);
aoqi@1 446 break;
aoqi@1 447
aoqi@1 448 case Assembler::fcvts_op:
aoqi@1 449 PRINT_CVT("cvt.s");
aoqi@1 450 break;
aoqi@1 451 case Assembler::fcvtd_op:
aoqi@1 452 PRINT_CVT("cvt.d");
aoqi@1 453 break;
aoqi@1 454 case Assembler::fcvtw_op:
aoqi@1 455 PRINT_CVT("cvt.w");
aoqi@1 456 break;
aoqi@1 457 case Assembler::fcvtl_op:
aoqi@1 458 PRINT_CVT("cvt.l");
aoqi@1 459 break;
aoqi@1 460 default:
aoqi@1 461 //tty->print_cr("0x%x(%x)", insn, opcode);
aoqi@1 462 //Unimplemented();
aoqi@1 463 env->print("0x%x\n", insn);
aoqi@1 464 }
aoqi@1 465 }
aoqi@1 466 break;
aoqi@1 467
aoqi@1 468 case Assembler::beql_op:
aoqi@1 469 case Assembler::bnel_op:
aoqi@1 470 case Assembler::blezl_op:
aoqi@1 471 case Assembler::bgtzl_op:
aoqi@1 472 PRINT_ORRL(Assembler::ops_name[opcode]);
aoqi@1 473 break;
aoqi@1 474
aoqi@1 475 case Assembler::ldl_op:
aoqi@1 476 case Assembler::ldr_op:
aoqi@1 477 case Assembler::lb_op:
aoqi@1 478 case Assembler::lh_op:
aoqi@1 479 case Assembler::lwl_op:
aoqi@1 480 case Assembler::lw_op:
aoqi@1 481 case Assembler::lbu_op:
aoqi@1 482 case Assembler::lhu_op:
aoqi@1 483 case Assembler::lwr_op:
aoqi@1 484 case Assembler::lwu_op:
aoqi@1 485 case Assembler::sb_op:
aoqi@1 486 case Assembler::sh_op:
aoqi@1 487 case Assembler::swl_op:
aoqi@1 488 case Assembler::sw_op:
aoqi@1 489 case Assembler::sdl_op:
aoqi@1 490 case Assembler::sdr_op:
aoqi@1 491 case Assembler::swr_op:
aoqi@1 492 case Assembler::ll_op:
aoqi@1 493 case Assembler::lld_op:
aoqi@1 494 case Assembler::ld_op:
aoqi@1 495 case Assembler::sc_op:
aoqi@1 496 case Assembler::scd_op:
aoqi@1 497 case Assembler::sd_op:
aoqi@1 498 PRINT_OROB(Assembler::ops_name[opcode]);
aoqi@1 499 break;
aoqi@1 500 case Assembler::sdc1_op:
aoqi@1 501 case Assembler::ldc1_op:
aoqi@1 502 case Assembler::lwc1_op:
aoqi@1 503 case Assembler::swc1_op:
aoqi@1 504 PRINT_OFOB(Assembler::ops_name[opcode]);
aoqi@1 505 break;
aoqi@1 506
aoqi@1 507 default:
aoqi@1 508 //tty->print_cr("0x%x(%x)", insn, opcode);
aoqi@1 509 //Unimplemented();
aoqi@1 510 env->print("0x%x\n", insn);
aoqi@1 511 }
aoqi@1 512
aoqi@1 513 return start+4;
aoqi@1 514 }
aoqi@1 515
aoqi@1 516 /*
aoqi@1 517 void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) {
aoqi@1 518 if (!load_library()) return;
aoqi@1 519 decode_env env(CodeCache::find_blob_unsafe(start), st, c);
aoqi@1 520 env.decode_instructions(start, end);
aoqi@1 521 }*/
aoqi@1 522
aoqi@1 523 void Disassembler::decode(CodeBlob* cb, outputStream* st) {
aoqi@1 524 #ifndef CORE
aoqi@1 525 st = st ? st : tty;
aoqi@1 526 st->print_cr("Decoding CodeBlob " INTPTR_FORMAT, cb);
aoqi@1 527 decode(cb->content_begin(), cb->content_end(), st);
aoqi@1 528 #endif
aoqi@1 529 }
aoqi@1 530
aoqi@1 531
aoqi@1 532 void Disassembler::decode(u_char* begin, u_char* end, outputStream* st) {
aoqi@1 533 st = st ? st : tty;
aoqi@1 534
aoqi@1 535 const int show_bytes = false; // for disassembler debugging
aoqi@1 536
aoqi@1 537 mips32_env env(NULL, st);
aoqi@1 538 unsigned char* p = (unsigned char*) begin;
aoqi@1 539 CodeBlob* cb = CodeCache::find_blob_unsafe(begin);
aoqi@1 540 while (p < (unsigned char*) end) {
aoqi@1 541 if (cb != NULL) {
aoqi@1 542 cb->print_block_comment(st, (unsigned char*)(p - cb->content_begin()));
aoqi@1 543 }
aoqi@1 544
aoqi@1 545
aoqi@1 546 unsigned char* p0 = p;
aoqi@1 547 st->print(" "INTPTR_FORMAT ": ", p);
aoqi@1 548 p = decode_instruction(p, &env);
aoqi@1 549 if (show_bytes) {
aoqi@1 550 st->print("\t\t\t");
aoqi@1 551 while (p0 < p) st->print("%x ", *p0++);
aoqi@1 552 }
aoqi@1 553 st->cr();
aoqi@1 554 }
aoqi@1 555 }
aoqi@1 556
aoqi@1 557
aoqi@1 558 void Disassembler::decode(nmethod* nm, outputStream* st) {
aoqi@1 559 #ifndef CORE
aoqi@1 560 st = st ? st : tty;
aoqi@1 561
aoqi@1 562 st->print_cr("Decoding compiled method " INTPTR_FORMAT ":", nm);
aoqi@1 563 st->print("Code:");
aoqi@1 564 st->cr();
aoqi@1 565
aoqi@1 566 mips32_env env(nm, st);
aoqi@1 567 #ifdef COMPILER1
aoqi@1 568 unsigned char* p = nm->code_begin();
aoqi@1 569 #else
aoqi@1 570 unsigned char* p = nm->content_begin();
aoqi@1 571 #endif
aoqi@1 572 unsigned char* end = nm->content_end();
aoqi@1 573 while (p < end) {
aoqi@1 574 if (p == nm->entry_point()) st->print_cr("[Entry Point]");
aoqi@1 575 if (p == nm->verified_entry_point()) st->print_cr("[Verified Entry Point]");
aoqi@1 576 if (p == nm->exception_begin()) st->print_cr("[Exception Handler]");
aoqi@1 577 if (p == nm->stub_begin()) st->print_cr("[Stub Code]");
aoqi@1 578 if (p == nm->consts_begin()) st->print_cr("[Constants]");
aoqi@1 579 nm->print_block_comment(st, (unsigned char*)(p - nm->content_begin()));
aoqi@1 580 unsigned char* p0 = p;
aoqi@1 581 st->print(" " INTPTR_FORMAT ": ", p);
aoqi@1 582 p = decode_instruction(p, &env);
aoqi@1 583 nm->print_code_comment_on(st, 40, p0, p);
aoqi@1 584 st->cr();
aoqi@1 585 // Output pc bucket ticks if we have any
aoqi@1 586 address bucket_pc = FlatProfiler::bucket_start_for(p);
aoqi@1 587 if (bucket_pc != NULL && bucket_pc > p0 && bucket_pc <= p) {
aoqi@1 588 int bucket_count = FlatProfiler::bucket_count_for(bucket_pc);
aoqi@1 589 tty->print_cr("[%d]", bucket_count);
aoqi@1 590 }
aoqi@1 591 }
aoqi@1 592 #endif
aoqi@1 593 }
aoqi@1 594
aoqi@1 595 #endif // PRODUCT
aoqi@1 596

mercurial