SPARCByteSwapOp.java revision 12651:6ef01bd40ce2
1169689Skan/*
2169689Skan * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
3169689Skan * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4169689Skan *
5169689Skan * This code is free software; you can redistribute it and/or modify it
6169689Skan * under the terms of the GNU General Public License version 2 only, as
7169689Skan * published by the Free Software Foundation.
8169689Skan *
9169689Skan * This code is distributed in the hope that it will be useful, but WITHOUT
10169689Skan * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11169689Skan * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12169689Skan * version 2 for more details (a copy is included in the LICENSE file that
13169689Skan * accompanied this code).
14169689Skan *
15169689Skan * You should have received a copy of the GNU General Public License version
16169689Skan * 2 along with this work; if not, write to the Free Software Foundation,
17169689Skan * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18169689Skan *
19169689Skan * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20169689Skan * or visit www.oracle.com if you need additional information or have any
21169689Skan * questions.
22169689Skan */
23169689Skanpackage org.graalvm.compiler.lir.sparc;
24169689Skan
25169689Skanimport static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
26169689Skanimport static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
27169689Skanimport static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
28169689Skanimport static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.UNINITIALIZED;
29169689Skanimport static jdk.vm.ci.code.ValueUtil.asRegister;
30169689Skanimport static jdk.vm.ci.sparc.SPARCKind.WORD;
31169689Skanimport static jdk.vm.ci.sparc.SPARCKind.XWORD;
32169689Skan
33169689Skanimport org.graalvm.compiler.asm.sparc.SPARCAddress;
34169689Skanimport org.graalvm.compiler.asm.sparc.SPARCAssembler.Asi;
35169689Skanimport org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
36169689Skanimport org.graalvm.compiler.core.common.LIRKind;
37169689Skanimport org.graalvm.compiler.debug.GraalError;
38169689Skanimport org.graalvm.compiler.lir.LIRInstructionClass;
39169689Skanimport org.graalvm.compiler.lir.Opcode;
40169689Skanimport org.graalvm.compiler.lir.asm.CompilationResultBuilder;
41169689Skanimport org.graalvm.compiler.lir.gen.LIRGeneratorTool;
42169689Skan
43169689Skanimport jdk.vm.ci.code.Register;
44169689Skanimport jdk.vm.ci.code.ValueUtil;
45169689Skanimport jdk.vm.ci.meta.AllocatableValue;
46169689Skanimport jdk.vm.ci.meta.Value;
47169689Skanimport jdk.vm.ci.sparc.SPARCKind;
48169689Skan
49169689Skan@Opcode("BSWAP")
50169689Skanpublic final class SPARCByteSwapOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
51169689Skan    public static final LIRInstructionClass<SPARCByteSwapOp> TYPE = LIRInstructionClass.create(SPARCByteSwapOp.class);
52169689Skan    public static final SizeEstimate SIZE = SizeEstimate.create(3);
53169689Skan    @Def({REG, HINT}) protected Value result;
54169689Skan    @Use({REG}) protected Value input;
55169689Skan    @Temp({REG}) protected Value tempIndex;
56169689Skan    @Use({STACK, UNINITIALIZED}) protected AllocatableValue tmpSlot;
57169689Skan
58169689Skan    public SPARCByteSwapOp(LIRGeneratorTool tool, Value result, Value input) {
59169689Skan        super(TYPE, SIZE);
60169689Skan        this.result = result;
61169689Skan        this.input = input;
62169689Skan        this.tmpSlot = tool.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(XWORD));
63169689Skan        this.tempIndex = tool.newVariable(LIRKind.value(XWORD));
64169689Skan    }
65169689Skan
66169689Skan    @Override
67169689Skan    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
68169689Skan        SPARCAddress addr = (SPARCAddress) crb.asAddress(tmpSlot);
69169689Skan        SPARCMove.emitStore(input, addr, result.getPlatformKind(), SPARCDelayedControlTransfer.DUMMY, null, crb, masm);
70169689Skan        if (addr.getIndex().equals(Register.None)) {
71169689Skan            Register tempReg = ValueUtil.asRegister(tempIndex, XWORD);
72169689Skan            masm.setx(addr.getDisplacement(), tempReg, false);
73169689Skan            addr = new SPARCAddress(addr.getBase(), tempReg);
74169689Skan        }
75169689Skan        getDelayedControlTransfer().emitControlTransfer(crb, masm);
76169689Skan        switch ((SPARCKind) input.getPlatformKind()) {
77169689Skan            case WORD:
78169689Skan                masm.lduwa(addr.getBase(), addr.getIndex(), asRegister(result, WORD), Asi.ASI_PRIMARY_LITTLE);
79169689Skan                break;
80169689Skan            case XWORD:
81169689Skan                masm.ldxa(addr.getBase(), addr.getIndex(), asRegister(result, XWORD), Asi.ASI_PRIMARY_LITTLE);
82169689Skan                break;
83169689Skan            default:
84169689Skan                throw GraalError.shouldNotReachHere();
85169689Skan        }
86169689Skan    }
87169689Skan}
88169689Skan