Tue, 26 Jul 2016 17:06:17 +0800
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