/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.jikesrvm.compilers.common.assembler.ia32;
import org.jikesrvm.VM;
import org.jikesrvm.ia32.RegisterConstants;
import org.vmmagic.unboxed.Offset;
import org.vmmagic.unboxed.Address;
import org.vmmagic.pragma.Pure;
/**
*/
public final class Lister implements RegisterConstants {
private static final int PREFIX_AREA_SIZE = 8;
private static final int OP_AREA_SIZE = 9;
private static final int SOURCE_AREA_SIZE = 16;
private static final int DEST_AREA_SIZE = 16;
private final Assembler asm;
private enum Prefix {LOCK, LIKELY, UNLIKELY};
private Prefix prefix;
public Lister(Assembler asm) {
this.asm = asm;
}
public void lockPrefix() {
prefix = Prefix.LOCK;
}
public void branchLikelyPrefix() {
prefix = Prefix.LIKELY;
}
public void branchUnlikelyPrefix() {
prefix = Prefix.UNLIKELY;
}
public void OP(int i, String op) {
i = begin(i, op);
VM.sysWrite(right("", DEST_AREA_SIZE));
VM.sysWrite(right("", SOURCE_AREA_SIZE));
end(i);
}
public void I(int i, String op, int n) {
i = begin(i, op);
VM.sysWrite(right(decimal(n) + " ", DEST_AREA_SIZE));
VM.sysWrite(right("", SOURCE_AREA_SIZE));
end(i);
}
public void R(int i, String op, MachineRegister R0) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("", SOURCE_AREA_SIZE));
end(i);
}
public void RD(int i, String op, MachineRegister R0, Offset d) {
i = begin(i, op);
VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE));
VM.sysWrite(right("", SOURCE_AREA_SIZE));
end(i);
}
public void RI(int i, String op, MachineRegister R0, long n) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right(decimal(n) + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RDI(int i, String op, MachineRegister R0, Offset d, long n) {
i = begin(i, op);
VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE));
VM.sysWrite(right(decimal(n) + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RNI(int i, String op, MachineRegister R0, long n) {
i = begin(i, op);
VM.sysWrite(right("[" + R0 + "]", DEST_AREA_SIZE));
VM.sysWrite(right(decimal(n) + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RR(int i, String op, MachineRegister R0, MachineRegister R1) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RDR(int i, String op, MachineRegister R0, Offset d, MachineRegister R1) {
i = begin(i, op);
VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RDRI(int i, String op, MachineRegister R0, Offset d, MachineRegister R1, int imm) {
i = begin(i, op);
VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE));
end(i);
}
public void RDRR(int i, String op, MachineRegister R0, Offset d, MachineRegister R1, MachineRegister R2) {
i = begin(i, op);
VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RRD(int i, String op, MachineRegister R0, MachineRegister R1, Offset d) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right(decimal(d) + "[" + R1 + "]", SOURCE_AREA_SIZE));
end(i);
}
public void RNR(int i, String op, MachineRegister R0, MachineRegister R1) {
i = begin(i, op);
VM.sysWrite(right("[" + R0 + "]", DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RN(int i, String op, MachineRegister R0) {
i = begin(i, op);
VM.sysWrite(right("[" + R0 + "]", DEST_AREA_SIZE));
VM.sysWrite(right(" ", SOURCE_AREA_SIZE));
end(i);
}
public void RRN(int i, String op, MachineRegister R0, MachineRegister R1) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + R1 + "]", SOURCE_AREA_SIZE));
end(i);
}
public void RXD(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d) {
i = begin(i, op);
VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]",
DEST_AREA_SIZE));
VM.sysWrite(right("", SOURCE_AREA_SIZE));
end(i);
}
public void RXDI(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, long n) {
i = begin(i, op);
VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]",
DEST_AREA_SIZE));
VM.sysWrite(right(decimal(n), SOURCE_AREA_SIZE));
end(i);
}
public void RFD(int i, String op, MachineRegister X, short s, Offset d) {
i = begin(i, op);
VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", DEST_AREA_SIZE));
VM.sysWrite(right("", SOURCE_AREA_SIZE));
end(i);
}
public void RA(int i, String op, Address d) {
i = begin(i, op);
VM.sysWrite(right("[" + hex(d) + "]", DEST_AREA_SIZE));
VM.sysWrite(right("", SOURCE_AREA_SIZE));
end(i);
}
public void RFDI(int i, String op, MachineRegister X, short s, Offset d, long n) {
i = begin(i, op);
VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", DEST_AREA_SIZE));
VM.sysWrite(right(decimal(n), SOURCE_AREA_SIZE));
end(i);
}
public void RAI(int i, String op, Address d, long n) {
i = begin(i, op);
VM.sysWrite(right("[" + hex(d) + "]", DEST_AREA_SIZE));
VM.sysWrite(right(decimal(n), SOURCE_AREA_SIZE));
end(i);
}
public void RRR(int i, String op, MachineRegister R0, MachineRegister R1, MachineRegister R2) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RNRI(int i, String op, MachineRegister R0, MachineRegister R1, int imm) {
i = begin(i, op);
VM.sysWrite(right("[" + R0 + "] ", DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE));
end(i);
}
public void RNRR(int i, String op, MachineRegister R0, MachineRegister R1, MachineRegister R2) {
i = begin(i, op);
VM.sysWrite(right("[" + R0 + "] ", DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RRI(int i, String op, MachineRegister R0, MachineRegister R1, int imm) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE));
end(i);
}
public void RRXD(int i, String op, MachineRegister R0, MachineRegister R1, MachineRegister X, short s, Offset d) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + decimal(d) + "+" + R1 + "+" + X + "<<" + decimal(s) + "]",
SOURCE_AREA_SIZE));
end(i);
}
public void RXDR(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, MachineRegister R1) {
i = begin(i, op);
VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]",
DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RXDRI(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, MachineRegister R1, int imm) {
i = begin(i, op);
VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]",
DEST_AREA_SIZE));
VM.sysWrite(right(R1 + " ", SOURCE_AREA_SIZE));
VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE));
end(i);
}
public void RXDRR(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, MachineRegister R1, MachineRegister R2) {
i = begin(i, op);
VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]",
SOURCE_AREA_SIZE));
VM.sysWrite(right(R1 + " ", DEST_AREA_SIZE));
VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RRFD(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", SOURCE_AREA_SIZE));
end(i);
}
public void RFDR(int i, String op, MachineRegister X, short s, Offset d, MachineRegister R0) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", SOURCE_AREA_SIZE));
end(i);
}
public void RFDRI(int i, String op, MachineRegister X, short s, Offset d, MachineRegister R0, int imm) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", SOURCE_AREA_SIZE));
VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE));
end(i);
}
public void RFDRR(int i, String op, MachineRegister X, short s, Offset d, MachineRegister R0, MachineRegister R2) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", SOURCE_AREA_SIZE));
VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE));
end(i);
}
public void RRA(int i, String op, MachineRegister R0, Address d) {
i = begin(i, op);
VM.sysWrite(right(R0 +" ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + hex(d) + "]", SOURCE_AREA_SIZE));
end(i);
}
public void RAR(int i, String op, Address d, MachineRegister R0) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + hex(d) + "]", SOURCE_AREA_SIZE));
end(i);
}
public void RARI(int i, String op, Address d, MachineRegister R0, int imm) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + hex(d) + "]", SOURCE_AREA_SIZE));
VM.sysWrite(right(decimal(imm), SOURCE_AREA_SIZE));
end(i);
}
public void RARR(int i, String op, Address d, MachineRegister R0, MachineRegister R2) {
i = begin(i, op);
VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE));
VM.sysWrite(right("[" + hex(d) + "]", SOURCE_AREA_SIZE));
VM.sysWrite(right(R2 + " ", SOURCE_AREA_SIZE));
end(i);
}
private int begin(int i, String op) {
if (prefix != null) i--;
VM.sysWrite(right(hex(i), 6) + "| ");
if (prefix != null) {
VM.sysWrite(right(prefix.toString(), PREFIX_AREA_SIZE) + " ");
} else {
VM.sysWrite(right("", PREFIX_AREA_SIZE) + " ");
}
VM.sysWrite(left(op, OP_AREA_SIZE));
return i;
}
private void end(int i) {
VM.sysWrite(" | ");
asm.writeLastInstruction(i);
VM.sysWrite("\n");
prefix = null;
}
@Pure
private static String left(String s, int w) {
int n = s.length();
if (w < n) return s.substring(0, w);
StringBuilder result = new StringBuilder(s);
for (int i = n; i < w; i++) {
result.append(' ');
}
return result.toString();
}
@Pure
private static String right(String s, int w) {
int n = s.length();
if (w < n) return s.substring(n - w);
StringBuilder result = new StringBuilder();
for (int i = n; i < w; i++) {
result.append(' ');
}
result.append(s);
return result.toString();
}
private static String decimal(Offset o) {
return decimal(o.toInt());
}
@Pure
static String decimal(int n) {
if (n == 0) return "0";
String sign = "";
if (n < 0) {
sign = "-";
n = -n;
}
String result = "";
while (0 < n) {
int i = n % 10;
n /= 10;
if (i == 0) {
result = "0" + result;
} else if (i == 1) {
result = "1" + result;
} else if (i == 2) {
result = "2" + result;
} else if (i == 3) {
result = "3" + result;
} else if (i == 4) {
result = "4" + result;
} else if (i == 5) {
result = "5" + result;
} else if (i == 6) {
result = "6" + result;
} else if (i == 7) {
result = "7" + result;
} else if (i == 8) {
result = "8" + result;
} else if (i == 9) result = "9" + result;
}
return (sign + result);
}
@Pure
static String decimal(long n) {
if (n == 0) return "0";
String sign = "";
if (n < 0) {
sign = "-";
n = -n;
}
String result = "";
while (0 < n) {
long i = n % 10;
n /= 10;
if (i == 0) {
result = "0" + result;
} else if (i == 1) {
result = "1" + result;
} else if (i == 2) {
result = "2" + result;
} else if (i == 3) {
result = "3" + result;
} else if (i == 4) {
result = "4" + result;
} else if (i == 5) {
result = "5" + result;
} else if (i == 6) {
result = "6" + result;
} else if (i == 7) {
result = "7" + result;
} else if (i == 8) {
result = "8" + result;
} else if (i == 9) result = "9" + result;
}
return (sign + result);
}
private static String decimal(short s) {
return decimal((int) s);
}
@Pure
static String hex(Address i) {
return (hex((short) (i.toInt() >> 16)) + hex((short) i.toWord().toInt()));
}
@Pure
public static String hex(int i) {
return (hex((short) (i >> 16)) + hex((short) i));
}
@Pure
static String hex(short i) {
return (hex((byte) (i >> 8)) + hex((byte) i));
}
@Pure
static String hex(byte b) {
int i = b & 0xFF;
byte j = (byte) (i / 0x10);
String s;
if (j == 0x0) {
s = "0";
} else if (j == 0x1) {
s = "1";
} else if (j == 0x2) {
s = "2";
} else if (j == 0x3) {
s = "3";
} else if (j == 0x4) {
s = "4";
} else if (j == 0x5) {
s = "5";
} else if (j == 0x6) {
s = "6";
} else if (j == 0x7) {
s = "7";
} else if (j == 0x8) {
s = "8";
} else if (j == 0x9) {
s = "9";
} else if (j == 0xA) {
s = "A";
} else if (j == 0xB) {
s = "B";
} else if (j == 0xC) {
s = "C";
} else if (j == 0xD) {
s = "D";
} else if (j == 0xE) {
s = "E";
} else {
s = "F";
}
j = (byte) (i % 0x10);
String t;
if (j == 0x0) {
t = "0";
} else if (j == 0x1) {
t = "1";
} else if (j == 0x2) {
t = "2";
} else if (j == 0x3) {
t = "3";
} else if (j == 0x4) {
t = "4";
} else if (j == 0x5) {
t = "5";
} else if (j == 0x6) {
t = "6";
} else if (j == 0x7) {
t = "7";
} else if (j == 0x8) {
t = "8";
} else if (j == 0x9) {
t = "9";
} else if (j == 0xA) {
t = "A";
} else if (j == 0xB) {
t = "B";
} else if (j == 0xC) {
t = "C";
} else if (j == 0xD) {
t = "D";
} else if (j == 0xE) {
t = "E";
} else {
t = "F";
}
return s + t;
}
public void noteBytecode(int i, String bcode) {
VM.sysWrite("[" + decimal(i) + "] " + bcode + "\n");
}
public void comment(int i, String comment) {
VM.sysWrite(right(hex(i), 6) + "| " + comment + "\n");
}
public void comefrom(int i, int j) {
VM.sysWrite(right(hex(i), 6) + "| <<< " + right(hex(j), 6) + "\n");
}
}