001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.jikesrvm.compilers.common.assembler.ia32; 014 015import org.jikesrvm.VM; 016import org.jikesrvm.architecture.MachineRegister; 017import org.vmmagic.unboxed.Offset; 018import org.vmmagic.unboxed.Address; 019import org.vmmagic.pragma.Pure; 020 021/** 022 */ 023public final class Lister { 024 025 private static final int PREFIX_AREA_SIZE = 8; 026 private static final int OP_AREA_SIZE = 9; 027 private static final int SOURCE_AREA_SIZE = 16; 028 private static final int DEST_AREA_SIZE = 16; 029 030 private final Assembler asm; 031 032 private enum Prefix {LOCK, LIKELY, UNLIKELY}; 033 034 private Prefix prefix; 035 036 public Lister(Assembler asm) { 037 this.asm = asm; 038 } 039 040 public void lockPrefix() { 041 prefix = Prefix.LOCK; 042 } 043 044 public void branchLikelyPrefix() { 045 prefix = Prefix.LIKELY; 046 } 047 048 public void branchUnlikelyPrefix() { 049 prefix = Prefix.UNLIKELY; 050 } 051 052 public void OP(int i, String op) { 053 i = begin(i, op); 054 VM.sysWrite(right("", DEST_AREA_SIZE)); 055 VM.sysWrite(right("", SOURCE_AREA_SIZE)); 056 end(i); 057 } 058 059 public void I(int i, String op, int n) { 060 i = begin(i, op); 061 VM.sysWrite(right(decimal(n) + " ", DEST_AREA_SIZE)); 062 VM.sysWrite(right("", SOURCE_AREA_SIZE)); 063 end(i); 064 } 065 066 public void R(int i, String op, MachineRegister R0) { 067 i = begin(i, op); 068 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 069 VM.sysWrite(right("", SOURCE_AREA_SIZE)); 070 end(i); 071 } 072 073 public void RD(int i, String op, MachineRegister R0, Offset d) { 074 i = begin(i, op); 075 VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE)); 076 VM.sysWrite(right("", SOURCE_AREA_SIZE)); 077 end(i); 078 } 079 080 public void RI(int i, String op, MachineRegister R0, long n) { 081 i = begin(i, op); 082 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 083 VM.sysWrite(right(decimal(n) + " ", SOURCE_AREA_SIZE)); 084 end(i); 085 } 086 087 public void RDI(int i, String op, MachineRegister R0, Offset d, long n) { 088 i = begin(i, op); 089 VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE)); 090 VM.sysWrite(right(decimal(n) + " ", SOURCE_AREA_SIZE)); 091 end(i); 092 } 093 094 public void RNI(int i, String op, MachineRegister R0, long n) { 095 i = begin(i, op); 096 VM.sysWrite(right("[" + R0 + "]", DEST_AREA_SIZE)); 097 VM.sysWrite(right(decimal(n) + " ", SOURCE_AREA_SIZE)); 098 end(i); 099 } 100 101 public void RR(int i, String op, MachineRegister R0, MachineRegister R1) { 102 i = begin(i, op); 103 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 104 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 105 end(i); 106 } 107 108 public void RDR(int i, String op, MachineRegister R0, Offset d, MachineRegister R1) { 109 i = begin(i, op); 110 VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE)); 111 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 112 end(i); 113 } 114 115 public void RDRI(int i, String op, MachineRegister R0, Offset d, MachineRegister R1, int imm) { 116 i = begin(i, op); 117 VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE)); 118 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 119 VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE)); 120 end(i); 121 } 122 123 public void RDRR(int i, String op, MachineRegister R0, Offset d, MachineRegister R1, MachineRegister R2) { 124 i = begin(i, op); 125 VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE)); 126 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 127 VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE)); 128 end(i); 129 } 130 131 public void RRD(int i, String op, MachineRegister R0, MachineRegister R1, Offset d) { 132 i = begin(i, op); 133 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 134 VM.sysWrite(right(decimal(d) + "[" + R1 + "]", SOURCE_AREA_SIZE)); 135 end(i); 136 } 137 138 public void RNR(int i, String op, MachineRegister R0, MachineRegister R1) { 139 i = begin(i, op); 140 VM.sysWrite(right("[" + R0 + "]", DEST_AREA_SIZE)); 141 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 142 end(i); 143 } 144 145 public void RN(int i, String op, MachineRegister R0) { 146 i = begin(i, op); 147 VM.sysWrite(right("[" + R0 + "]", DEST_AREA_SIZE)); 148 VM.sysWrite(right(" ", SOURCE_AREA_SIZE)); 149 end(i); 150 } 151 152 public void RRN(int i, String op, MachineRegister R0, MachineRegister R1) { 153 i = begin(i, op); 154 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 155 VM.sysWrite(right("[" + R1 + "]", SOURCE_AREA_SIZE)); 156 end(i); 157 } 158 159 public void RXD(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d) { 160 i = begin(i, op); 161 VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]", 162 DEST_AREA_SIZE)); 163 VM.sysWrite(right("", SOURCE_AREA_SIZE)); 164 end(i); 165 } 166 167 public void RXDI(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, long n) { 168 i = begin(i, op); 169 VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]", 170 DEST_AREA_SIZE)); 171 VM.sysWrite(right(decimal(n), SOURCE_AREA_SIZE)); 172 end(i); 173 } 174 175 public void RFD(int i, String op, MachineRegister X, short s, Offset d) { 176 i = begin(i, op); 177 VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", DEST_AREA_SIZE)); 178 VM.sysWrite(right("", SOURCE_AREA_SIZE)); 179 end(i); 180 } 181 182 public void RA(int i, String op, Address d) { 183 i = begin(i, op); 184 VM.sysWrite(right("[" + hex(d) + "]", DEST_AREA_SIZE)); 185 VM.sysWrite(right("", SOURCE_AREA_SIZE)); 186 end(i); 187 } 188 189 public void RFDI(int i, String op, MachineRegister X, short s, Offset d, long n) { 190 i = begin(i, op); 191 VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", DEST_AREA_SIZE)); 192 VM.sysWrite(right(decimal(n), SOURCE_AREA_SIZE)); 193 end(i); 194 } 195 196 public void RAI(int i, String op, Address d, long n) { 197 i = begin(i, op); 198 VM.sysWrite(right("[" + hex(d) + "]", DEST_AREA_SIZE)); 199 VM.sysWrite(right(decimal(n), SOURCE_AREA_SIZE)); 200 end(i); 201 } 202 203 public void RRR(int i, String op, MachineRegister R0, MachineRegister R1, MachineRegister R2) { 204 i = begin(i, op); 205 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 206 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 207 VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE)); 208 end(i); 209 } 210 211 public void RNRI(int i, String op, MachineRegister R0, MachineRegister R1, int imm) { 212 i = begin(i, op); 213 VM.sysWrite(right("[" + R0 + "] ", DEST_AREA_SIZE)); 214 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 215 VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE)); 216 end(i); 217 } 218 219 public void RNRR(int i, String op, MachineRegister R0, MachineRegister R1, MachineRegister R2) { 220 i = begin(i, op); 221 VM.sysWrite(right("[" + R0 + "] ", DEST_AREA_SIZE)); 222 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 223 VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE)); 224 end(i); 225 } 226 227 public void RRI(int i, String op, MachineRegister R0, MachineRegister R1, int imm) { 228 i = begin(i, op); 229 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 230 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 231 VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE)); 232 end(i); 233 } 234 235 public void RRXD(int i, String op, MachineRegister R0, MachineRegister R1, MachineRegister X, short s, Offset d) { 236 i = begin(i, op); 237 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 238 VM.sysWrite(right("[" + decimal(d) + "+" + R1 + "+" + X + "<<" + decimal(s) + "]", 239 SOURCE_AREA_SIZE)); 240 end(i); 241 } 242 243 public void RXDR(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, MachineRegister R1) { 244 i = begin(i, op); 245 VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]", 246 DEST_AREA_SIZE)); 247 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 248 end(i); 249 } 250 251 public void RXDRI(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, MachineRegister R1, int imm) { 252 i = begin(i, op); 253 VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]", 254 DEST_AREA_SIZE)); 255 VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE)); 256 VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE)); 257 end(i); 258 } 259 260 public void RXDRR(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, MachineRegister R1, MachineRegister R2) { 261 i = begin(i, op); 262 VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]", 263 SOURCE_AREA_SIZE)); 264 VM.sysWrite(right(R1 + " ", DEST_AREA_SIZE)); 265 VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE)); 266 end(i); 267 } 268 269 public void RRFD(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d) { 270 i = begin(i, op); 271 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 272 VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", SOURCE_AREA_SIZE)); 273 end(i); 274 } 275 276 public void RFDR(int i, String op, MachineRegister X, short s, Offset d, MachineRegister R0) { 277 i = begin(i, op); 278 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 279 VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", SOURCE_AREA_SIZE)); 280 end(i); 281 } 282 283 public void RFDRI(int i, String op, MachineRegister X, short s, Offset d, MachineRegister R0, int imm) { 284 i = begin(i, op); 285 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 286 VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", SOURCE_AREA_SIZE)); 287 VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE)); 288 end(i); 289 } 290 291 public void RFDRR(int i, String op, MachineRegister X, short s, Offset d, MachineRegister R0, MachineRegister R2) { 292 i = begin(i, op); 293 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 294 VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", SOURCE_AREA_SIZE)); 295 VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE)); 296 end(i); 297 } 298 299 public void RRA(int i, String op, MachineRegister R0, Address d) { 300 i = begin(i, op); 301 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 302 VM.sysWrite(right("[" + hex(d) + "]", SOURCE_AREA_SIZE)); 303 end(i); 304 } 305 306 public void RAR(int i, String op, Address d, MachineRegister R0) { 307 i = begin(i, op); 308 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 309 VM.sysWrite(right("[" + hex(d) + "]", SOURCE_AREA_SIZE)); 310 end(i); 311 } 312 313 public void RARI(int i, String op, Address d, MachineRegister R0, int imm) { 314 i = begin(i, op); 315 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 316 VM.sysWrite(right("[" + hex(d) + "]", SOURCE_AREA_SIZE)); 317 VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE)); 318 end(i); 319 } 320 321 public void RARR(int i, String op, Address d, MachineRegister R0, MachineRegister R2) { 322 i = begin(i, op); 323 VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); 324 VM.sysWrite(right("[" + hex(d) + "]", SOURCE_AREA_SIZE)); 325 VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE)); 326 end(i); 327 } 328 329 private int begin(int i, String op) { 330 if (prefix != null) i--; 331 VM.sysWrite(right(hex(i), 6) + "| "); 332 if (prefix != null) { 333 VM.sysWrite(right(prefix.toString(), PREFIX_AREA_SIZE) + " "); 334 } else { 335 VM.sysWrite(right("", PREFIX_AREA_SIZE) + " "); 336 } 337 VM.sysWrite(left(op, OP_AREA_SIZE)); 338 return i; 339 } 340 341 private void end(int i) { 342 VM.sysWrite(" | "); 343 asm.writeLastInstruction(i); 344 VM.sysWrite("\n"); 345 prefix = null; 346 } 347 348 @Pure 349 private static String left(String s, int w) { 350 int n = s.length(); 351 if (w < n) return s.substring(0, w); 352 StringBuilder result = new StringBuilder(s); 353 for (int i = n; i < w; i++) { 354 result.append(' '); 355 } 356 return result.toString(); 357 } 358 359 @Pure 360 private static String right(String s, int w) { 361 int n = s.length(); 362 if (w < n) return s.substring(n - w); 363 StringBuilder result = new StringBuilder(); 364 for (int i = n; i < w; i++) { 365 result.append(' '); 366 } 367 result.append(s); 368 return result.toString(); 369 } 370 371 private static String decimal(Offset o) { 372 return decimal(o.toInt()); 373 } 374 375 @Pure 376 static String decimal(int n) { 377 if (n == 0) return "0"; 378 String sign = ""; 379 if (n < 0) { 380 sign = "-"; 381 n = -n; 382 } 383 String result = ""; 384 while (0 < n) { 385 int i = n % 10; 386 n /= 10; 387 if (i == 0) { 388 result = "0" + result; 389 } else if (i == 1) { 390 result = "1" + result; 391 } else if (i == 2) { 392 result = "2" + result; 393 } else if (i == 3) { 394 result = "3" + result; 395 } else if (i == 4) { 396 result = "4" + result; 397 } else if (i == 5) { 398 result = "5" + result; 399 } else if (i == 6) { 400 result = "6" + result; 401 } else if (i == 7) { 402 result = "7" + result; 403 } else if (i == 8) { 404 result = "8" + result; 405 } else if (i == 9) result = "9" + result; 406 } 407 return (sign + result); 408 } 409 410 @Pure 411 static String decimal(long n) { 412 if (n == 0) return "0"; 413 String sign = ""; 414 if (n < 0) { 415 sign = "-"; 416 n = -n; 417 } 418 String result = ""; 419 while (0 < n) { 420 long i = n % 10; 421 n /= 10; 422 if (i == 0) { 423 result = "0" + result; 424 } else if (i == 1) { 425 result = "1" + result; 426 } else if (i == 2) { 427 result = "2" + result; 428 } else if (i == 3) { 429 result = "3" + result; 430 } else if (i == 4) { 431 result = "4" + result; 432 } else if (i == 5) { 433 result = "5" + result; 434 } else if (i == 6) { 435 result = "6" + result; 436 } else if (i == 7) { 437 result = "7" + result; 438 } else if (i == 8) { 439 result = "8" + result; 440 } else if (i == 9) result = "9" + result; 441 } 442 return (sign + result); 443 } 444 445 private static String decimal(short s) { 446 return decimal((int) s); 447 } 448 449 @Pure 450 static String hex(Address i) { 451 return (hex((short) (i.toInt() >> 16)) + hex((short) i.toWord().toInt())); 452 } 453 454 @Pure 455 public static String hex(int i) { 456 return (hex((short) (i >> 16)) + hex((short) i)); 457 } 458 459 @Pure 460 static String hex(short i) { 461 return (hex((byte) (i >> 8)) + hex((byte) i)); 462 } 463 464 @Pure 465 static String hex(byte b) { 466 int i = b & 0xFF; 467 byte j = (byte) (i / 0x10); 468 String s; 469 if (j == 0x0) { 470 s = "0"; 471 } else if (j == 0x1) { 472 s = "1"; 473 } else if (j == 0x2) { 474 s = "2"; 475 } else if (j == 0x3) { 476 s = "3"; 477 } else if (j == 0x4) { 478 s = "4"; 479 } else if (j == 0x5) { 480 s = "5"; 481 } else if (j == 0x6) { 482 s = "6"; 483 } else if (j == 0x7) { 484 s = "7"; 485 } else if (j == 0x8) { 486 s = "8"; 487 } else if (j == 0x9) { 488 s = "9"; 489 } else if (j == 0xA) { 490 s = "A"; 491 } else if (j == 0xB) { 492 s = "B"; 493 } else if (j == 0xC) { 494 s = "C"; 495 } else if (j == 0xD) { 496 s = "D"; 497 } else if (j == 0xE) { 498 s = "E"; 499 } else { 500 s = "F"; 501 } 502 j = (byte) (i % 0x10); 503 String t; 504 if (j == 0x0) { 505 t = "0"; 506 } else if (j == 0x1) { 507 t = "1"; 508 } else if (j == 0x2) { 509 t = "2"; 510 } else if (j == 0x3) { 511 t = "3"; 512 } else if (j == 0x4) { 513 t = "4"; 514 } else if (j == 0x5) { 515 t = "5"; 516 } else if (j == 0x6) { 517 t = "6"; 518 } else if (j == 0x7) { 519 t = "7"; 520 } else if (j == 0x8) { 521 t = "8"; 522 } else if (j == 0x9) { 523 t = "9"; 524 } else if (j == 0xA) { 525 t = "A"; 526 } else if (j == 0xB) { 527 t = "B"; 528 } else if (j == 0xC) { 529 t = "C"; 530 } else if (j == 0xD) { 531 t = "D"; 532 } else if (j == 0xE) { 533 t = "E"; 534 } else { 535 t = "F"; 536 } 537 return s + t; 538 } 539 540 public void noteBytecode(int i, String bcode) { 541 VM.sysWrite("[" + decimal(i) + "] " + bcode + "\n"); 542 } 543 544 public void comment(int i, String comment) { 545 VM.sysWrite(right(hex(i), 6) + "| " + comment + "\n"); 546 } 547 548 public void comefrom(int i, int j) { 549 VM.sysWrite(right(hex(i), 6) + "| <<< " + right(hex(j), 6) + "\n"); 550 } 551}