Mercurial > hg > truffle
view graal/com.oracle.max.asmdis/src/com/sun/max/asm/sparc/complete/SPARCAssembler.java @ 4281:62cb0e636094
Copyright fixes
author | Christian Wimmer <Christian.Wimmer@Oracle.com> |
---|---|
date | Thu, 12 Jan 2012 13:48:27 -0800 |
parents | bc8527f3071c |
children |
line wrap: on
line source
/* * 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. */ @SuppressWarnings("unused") 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); } }; } }