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 */
013 package org.jikesrvm.compilers.common.assembler.ia32;
014
015 import org.jikesrvm.VM;
016 import org.jikesrvm.ia32.RegisterConstants;
017 import org.vmmagic.unboxed.Offset;
018 import org.vmmagic.unboxed.Address;
019 import org.vmmagic.pragma.Pure;
020
021 /**
022 */
023 public final class Lister implements RegisterConstants {
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 }