Mercurial > hg > truffle
diff graal/com.oracle.max.asmdis/src/com/sun/max/asm/sparc/complete/SPARCAssembler.java @ 3733:e233f5660da4
Added Java files from Maxine project.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 19:59:18 +0100 |
parents | |
children | bc8527f3071c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.asmdis/src/com/sun/max/asm/sparc/complete/SPARCAssembler.java Sat Dec 17 19:59:18 2011 +0100 @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.max.asm.sparc.complete; + +import static com.sun.max.asm.sparc.GPR.*; + +import com.sun.max.asm.*; +import com.sun.max.asm.sparc.*; +import com.sun.max.lang.*; +import com.sun.max.program.*; + +/** + * The base class for the 32-bit and 64-bit SPARC assemblers. This class also defines + * the more complex synthetic SPARC instructions. + */ +public abstract class SPARCAssembler extends SPARCLabelAssembler { + + public static SPARCAssembler createAssembler(WordWidth wordWidth) { + switch (wordWidth) { + case BITS_32: + return new SPARC32Assembler(); + case BITS_64: + return new SPARC64Assembler(); + default: + throw ProgramError.unexpected("Invalid word width specification"); + } + } + + // Utilities: + + public static int hi(int i) { + return (i & 0xfffffc00) >> 10; + } + + public static int lo(int i) { + return i & 0x000003ff; + } + + public static int hi(long i) { + return hi((int) i); + } + + public static int lo(long i) { + return lo((int) i); + } + + public static int uhi(long i) { + return hi((int) (i >> 32)); + } + + public static int ulo(long i) { + return lo((int) (i >> 32)); + } + + public static boolean isSimm11(int value) { + return Ints.numberOfEffectiveSignedBits(value) <= 11; + } + + public static boolean isSimm13(int value) { + return Ints.numberOfEffectiveSignedBits(value) <= 13; + } + + public static boolean isSimm13(long value) { + return Longs.numberOfEffectiveSignedBits(value) <= 13; + } + + public static boolean isSimm19(int value) { + return Ints.numberOfEffectiveSignedBits(value) <= 19; + } + + public static int setswNumberOfInstructions(int imm) { + if (0 <= imm && lo(imm) == 0) { + return 1; + } else if (-4096 <= imm && imm <= 4095) { + return 1; + } else if (imm >= 0 || lo(imm) == 0) { + return 2; + } else { + return 3; + } + } + + public static int setuwNumberOfInstructions(int imm) { + if (lo(imm) == 0) { + return 1; + } else if (0 <= imm && imm <= 4095) { + return 1; + } else { + return 2; + } + } + + @Override + protected void emitPadding(int numberOfBytes) throws AssemblyException { + if ((numberOfBytes & 0x3) != 0) { + throw new AssemblyException("Cannot pad instruction stream with a number of bytes not divisble by 4"); + } + for (int i = 0; i < numberOfBytes >> 2; i++) { + nop(); + } + } + + // Complex synthetic instructions according to appendix G3 of the SPARC Architecture Manual V9: + + public void setuw(int imm, GPR rd) { + if (lo(imm) == 0) { + sethi(hi(imm), rd); + } else if (0 <= imm && imm <= 4095) { + or(G0, imm, rd); + } else { + sethi(hi(imm), rd); + or(rd, lo(imm), rd); + } + } + + public void set(int imm, GPR rd) { + setuw(imm, rd); + } + + public void setsw(int imm, GPR rd) { + if (0 <= imm && lo(imm) == 0) { + sethi(hi(imm), rd); + } else if (-4096 <= imm && imm <= 4095) { + or(G0, imm, rd); + } else if (imm < 0 && lo(imm) == 0) { + sethi(hi(imm), rd); + sra(rd, G0, rd); + } else if (imm >= 0) { + sethi(hi(imm), rd); + or(rd, lo(imm), rd); + } else { + sethi(hi(imm), rd); + or(rd, lo(imm), rd); + sra(rd, G0, rd); + } + } + + public void setx(long imm, GPR temp, GPR rd) { + sethi(uhi(imm), temp); + or(temp, ulo(imm), temp); + sllx(temp, 32, temp); + sethi(hi(imm), rd); + or(rd, temp, rd); + or(rd, lo(imm), rd); + } + + public void sethi(Label label, final GPR rd) { + final int startPosition = currentPosition(); + emitInt(0); + new InstructionWithAddress(this, startPosition, startPosition + 4, label) { + @Override + protected void assemble() throws AssemblyException { + final int imm22 = hi(addressAsInt()); + sethi(imm22, rd); + } + }; + } + + public void add(final GPR rs1, final Label label, final GPR rd) { + final int startPosition = currentPosition(); + emitInt(0); + new InstructionWithAddress(this, startPosition, startPosition + 4, label) { + @Override + protected void assemble() throws AssemblyException { + final int simm13 = lo(addressAsInt()); + add(rs1, simm13, rd); + } + }; + } + + public void ld(final GPR rs1, final Label base, final Label target, final SFPR rd) { + final int startPosition = currentPosition(); + emitInt(0); + new InstructionWithOffset(this, startPosition, startPosition + 4, target) { + @Override + protected void assemble() throws AssemblyException { + ld(rs1, labelOffsetRelative(target, base), rd); + } + }; + } + + public void ldd(final GPR rs1, final Label base, final Label target, final DFPR rd) { + final int startPosition = currentPosition(); + emitInt(0); + new InstructionWithOffset(this, startPosition, startPosition + 4, target) { + @Override + protected void assemble() throws AssemblyException { + ldd(rs1, labelOffsetRelative(target, base), rd); + } + }; + } + + public void ldx(final GPR rs1, final Label base, final Label target, final GPR rd) { + final int startPosition = currentPosition(); + emitInt(0); + new InstructionWithOffset(this, startPosition, startPosition + 4, target) { + @Override + protected void assemble() throws AssemblyException { + ldx(rs1, labelOffsetRelative(target, base), rd); + } + }; + } + + public void add(final GPR rs1, final Label base, final Label target, final GPR rd) { + final int startPosition = currentPosition(); + emitInt(0); + new InstructionWithOffset(this, startPosition, startPosition + 4, target) { + @Override + protected void assemble() throws AssemblyException { + add(rs1, labelOffsetRelative(target, base), rd); + } + }; + } + public void addcc(final GPR rs1, final Label base, final Label target, final GPR rd) { + final int startPosition = currentPosition(); + emitInt(0); + new InstructionWithOffset(this, startPosition, startPosition + 4, target) { + @Override + protected void assemble() throws AssemblyException { + addcc(rs1, labelOffsetRelative(target, base), rd); + } + }; + } +}