/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.assembler.x86;
import org.jnode.vm.objects.BootableHashMap;
import org.jnode.vm.objects.VmSystemObject;
/**
* Registers of the x86 architecture.
*
* @author epr
* @author Levente S\u00e1ntha (lsantha@users.sourceforge.net)
*/
public class X86Register extends VmSystemObject implements X86Constants {
//Register map, it should stand ahead of any register constant !!!
private static final BootableHashMap<String, X86Register> registerMap = new BootableHashMap<String, X86Register>();
/* 8-bit GPR registers */
public static final GPR8 AL = new GPR8("al", 0);
public static final GPR8 BL = new GPR8("bl", 3);
public static final GPR8 CL = new GPR8("cl", 1);
public static final GPR8 DL = new GPR8("dl", 2);
public static final GPR8 AH = new GPR8("ah", 4);
public static final GPR8 BH = new GPR8("bh", 7);
public static final GPR8 CH = new GPR8("ch", 5);
public static final GPR8 DH = new GPR8("dh", 6);
/* 16-bit GPR registers */
public static final GPR16 AX = new GPR16("ax", 0, true);
public static final GPR16 BX = new GPR16("bx", 3, true);
public static final GPR16 CX = new GPR16("cx", 1, true);
public static final GPR16 DX = new GPR16("dx", 2, true);
public static final GPR16 SP = new GPR16("sp", 4);
public static final GPR16 BP = new GPR16("bp", 5);
public static final GPR16 SI = new GPR16("si", 6);
public static final GPR16 DI = new GPR16("di", 7);
/* 32-bit GPR registers */
public static final GPR32 EAX = new GPR32("eax", 0, true);
public static final GPR32 EBX = new GPR32("ebx", 3, true);
public static final GPR32 ECX = new GPR32("ecx", 1, true);
public static final GPR32 EDX = new GPR32("edx", 2, true);
public static final GPR32 ESP = new GPR32("esp", 4);
public static final GPR32 EBP = new GPR32("ebp", 5);
public static final GPR32 ESI = new GPR32("esi", 6);
public static final GPR32 EDI = new GPR32("edi", 7);
/* 64-bit GPR registers */
public static final GPR64 RAX = new GPR64("rax", 0);
public static final GPR64 RBX = new GPR64("rbx", 3);
public static final GPR64 RCX = new GPR64("rcx", 1);
public static final GPR64 RDX = new GPR64("rdx", 2);
public static final GPR64 RSP = new GPR64("rsp", 4);
public static final GPR64 RBP = new GPR64("rbp", 5);
public static final GPR64 RSI = new GPR64("rsi", 6);
public static final GPR64 RDI = new GPR64("rdi", 7);
public static final GPR64 R8 = new GPR64("r8", 8);
public static final GPR64 R9 = new GPR64("r9", 9);
public static final GPR64 R10 = new GPR64("r10", 10);
public static final GPR64 R11 = new GPR64("r11", 11);
public static final GPR64 R12 = new GPR64("r12", 12);
public static final GPR64 R13 = new GPR64("r13", 13);
public static final GPR64 R14 = new GPR64("r14", 14);
public static final GPR64 R15 = new GPR64("r15", 15);
public static final GPR32 R8d = new GPR32("r8d", 8, true);
public static final GPR32 R9d = new GPR32("r9d", 9, true);
public static final GPR32 R10d = new GPR32("r10d", 10, true);
public static final GPR32 R11d = new GPR32("r11d", 11, true);
public static final GPR32 R12d = new GPR32("r12d", 12, true);
public static final GPR32 R13d = new GPR32("r13d", 13, true);
public static final GPR32 R14d = new GPR32("r14d", 14, true);
public static final GPR32 R15d = new GPR32("r15d", 15, true);
/*Segment registers*/
public static final SR ES = new SR("es", 0);
public static final SR CS = new SR("cs", 1);
public static final SR SS = new SR("ss", 2);
public static final SR DS = new SR("ds", 3);
public static final SR FS = new SR("fs", 4);
public static final SR GS = new SR("gs", 5);
/*Control registers*/
public static final CRX CR0 = new CRX("cr0", 0);
public static final CRX CR2 = new CRX("cr2", 2);
public static final CRX CR3 = new CRX("cr3", 3);
public static final CRX CR4 = new CRX("cr4", 4);
/* Floating-point registers */
public static final FPU ST0 = new FPU("st0", 0);
public static final FPU ST1 = new FPU("st1", 1);
public static final FPU ST2 = new FPU("st2", 2);
public static final FPU ST3 = new FPU("st3", 3);
public static final FPU ST4 = new FPU("st4", 4);
public static final FPU ST5 = new FPU("st5", 5);
public static final FPU ST6 = new FPU("st6", 6);
public static final FPU ST7 = new FPU("st7", 7);
/* MMX registers */
public static final MMX MM0 = new MMX("mm0", 0);
public static final MMX MM1 = new MMX("mm1", 1);
public static final MMX MM2 = new MMX("mm2", 2);
public static final MMX MM3 = new MMX("mm3", 3);
public static final MMX MM4 = new MMX("mm4", 4);
public static final MMX MM5 = new MMX("mm5", 5);
public static final MMX MM6 = new MMX("mm6", 6);
public static final MMX MM7 = new MMX("mm7", 7);
/* SSE registers */
public static final XMM XMM0 = new XMM("xmm0", 0);
public static final XMM XMM1 = new XMM("xmm1", 1);
public static final XMM XMM2 = new XMM("xmm2", 2);
public static final XMM XMM3 = new XMM("xmm3", 3);
public static final XMM XMM4 = new XMM("xmm4", 4);
public static final XMM XMM5 = new XMM("xmm5", 5);
public static final XMM XMM6 = new XMM("xmm6", 6);
public static final XMM XMM7 = new XMM("xmm7", 7);
public static final XMM XMM8 = new XMM("xmm8", 8);
public static final XMM XMM9 = new XMM("xmm9", 9);
public static final XMM XMM10 = new XMM("xmm10", 10);
public static final XMM XMM11 = new XMM("xmm11", 11);
public static final XMM XMM12 = new XMM("xmm12", 12);
public static final XMM XMM13 = new XMM("xmm13", 13);
public static final XMM XMM14 = new XMM("xmm14", 14);
public static final XMM XMM15 = new XMM("xmm15", 15);
private final String name;
private final int nr;
private final int size;
private final boolean suitableFor8Bit;
public X86Register(String name, int size, int nr) {
this(name, size, nr, false);
}
public X86Register(String name, int size, int nr, boolean suitableFor8Bit) {
this.name = name;
this.nr = nr;
this.size = size;
this.suitableFor8Bit = suitableFor8Bit;
registerMap.put(name, this);
}
/**
* Returns the name.
*
* @return String
*/
public final String getName() {
return name;
}
/**
* Returns the nr.
*
* @return int
*/
public final int getNr() {
return nr;
}
/**
* Returns the size of this register
*
* @return int
* @see X86Constants#BITS8
* @see X86Constants#BITS16
* @see X86Constants#BITS32
* @see X86Constants#BITS64
* @see X86Constants#BITS80
*/
public final int getSize() {
return size;
}
public final String toString() {
return name;
}
/**
* Does this register have an 8-bit part.
*
* @return True for EAX, EBX, ECX, EDX, false otherwise.
*/
public final boolean isSuitableForBits8() {
return suitableFor8Bit;
}
public static GPR getGPR(String name) {
Object obj = registerMap.get(name);
if (obj == null) throw new IllegalArgumentException("Unknown register: " + name);
if (!(obj instanceof GPR)) throw new IllegalArgumentException("Not a GPR: " + name);
return (GPR) obj;
}
public static boolean isGPR(String name) {
Object obj = registerMap.get(name);
return (obj != null) && (obj instanceof GPR);
}
public static X86Register getRegister(String name) {
Object obj = registerMap.get(name);
if (obj == null) throw new IllegalArgumentException("Unknown register: " + name);
if (!(obj instanceof X86Register)) throw new IllegalArgumentException("Not a X86Register: " + name);
return (X86Register) obj;
}
public static boolean isRegister(String name) {
Object obj = registerMap.get(name);
return (obj != null) && (obj instanceof X86Register);
}
public abstract static class GPR extends X86Register {
/**
* @param name
* @param size
* @param nr
*/
public GPR(String name, int size, int nr) {
super(name, size, nr);
}
/**
* @param name
* @param size
* @param nr
* @param suitableFor8Bit
*/
public GPR(String name, int size, int nr, boolean suitableFor8Bit) {
super(name, size, nr, suitableFor8Bit);
}
}
public static class GPR8 extends GPR {
/**
* @param name
* @param nr
*/
public GPR8(String name, int nr) {
super(name, X86Constants.BITS8, nr, true);
}
}
public static class GPR16 extends GPR {
/**
* @param name
* @param nr
*/
public GPR16(String name, int nr) {
super(name, X86Constants.BITS16, nr);
}
/**
* @param name
* @param nr
* @param suitableFor8Bit
*/
public GPR16(String name, int nr, boolean suitableFor8Bit) {
super(name, X86Constants.BITS16, nr, suitableFor8Bit);
}
}
public static class GPR32 extends GPR {
/**
* @param name
* @param nr
*/
public GPR32(String name, int nr) {
super(name, X86Constants.BITS32, nr);
}
/**
* @param name
* @param nr
* @param suitableFor8Bit
*/
public GPR32(String name, int nr, boolean suitableFor8Bit) {
super(name, X86Constants.BITS32, nr, suitableFor8Bit);
}
}
public static final class GPR64 extends GPR {
/**
* @param name
* @param nr
*/
public GPR64(String name, int nr) {
super(name, X86Constants.BITS64, nr, true);
}
}
public static final class FPU extends X86Register {
/**
* @param name
* @param nr
*/
public FPU(String name, int nr) {
super(name, X86Constants.BITS80, nr);
}
}
public static final class MMX extends X86Register {
/**
* @param name
* @param nr
*/
public MMX(String name, int nr) {
super(name, X86Constants.BITS64, nr);
}
}
public static final class XMM extends X86Register {
/**
* @param name
* @param nr
*/
public XMM(String name, int nr) {
super(name, X86Constants.BITS128, nr);
}
}
public static final class CRX extends X86Register {
/**
* @param name
* @param nr
*/
public CRX(String name, int nr) {
super(name, X86Constants.BITS32, nr, false);
}
}
public static final class SR extends X86Register {
/**
* @param name
* @param nr
*/
public SR(String name, int nr) {
super(name, X86Constants.BITS16, nr, false);
}
}
}