src/cpu/mips/vm/disassembler_mips.cpp

Tue, 26 Jul 2016 17:06:17 +0800

author
fujie
date
Tue, 26 Jul 2016 17:06:17 +0800
changeset 41
d885f8d65c58
parent 38
f0e26f502a50
child 44
a98aa769eb1d
permissions
-rw-r--r--

Add multiply word to GPR instruction (mul) in MIPS assembler.

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

mercurial