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    }