mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-16 16:37:42 +00:00
Add 64-bit shift instructions.
SPARC v9 defines new 64-bit shift instructions. The 32-bit shift right instructions are still usable as zero and sign extensions. This adds new F3_Sr and F3_Si instruction formats that probably should be used for the 32-bit shifts as well. They don't really encode an simm13 field. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178525 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a10fd6d3d1
commit
c3ff3f42ee
47
lib/Target/Sparc/SparcInstr64Bit.td
Normal file
47
lib/Target/Sparc/SparcInstr64Bit.td
Normal file
@ -0,0 +1,47 @@
|
||||
//===-- SparcInstr64Bit.td - 64-bit instructions for Sparc Target ---------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains instruction definitions and patterns needed for 64-bit
|
||||
// code generation on SPARC v9.
|
||||
//
|
||||
// Some SPARC v9 instructions are defined in SparcInstrInfo.td because they can
|
||||
// also be used in 32-bit code running on a SPARC v9 CPU.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Predicates = [Is64Bit] in {
|
||||
// The same integer registers are used for i32 and i64 values.
|
||||
// When registers hold i32 values, the high bits are don't care.
|
||||
// This give us free trunc and anyext.
|
||||
def : Pat<(i64 (anyext i32:$val)), (COPY $val)>;
|
||||
def : Pat<(i32 (trunc i64:$val)), (COPY $val)>;
|
||||
|
||||
} // Predicates = [Is64Bit]
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 64-bit Shift Instructions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The 32-bit shift instructions are still available. The left shift srl
|
||||
// instructions shift all 64 bits, but it only accepts a 5-bit shift amount.
|
||||
//
|
||||
// The srl instructions only shift the low 32 bits and clear the high 32 bits.
|
||||
// Finally, sra shifts the low 32 bits and sign-extends to 64 bits.
|
||||
|
||||
let Predicates = [Is64Bit] in {
|
||||
|
||||
def : Pat<(i64 (zext i32:$val)), (SRLri $val, 0)>;
|
||||
def : Pat<(i64 (sext i32:$val)), (SRAri $val, 0)>;
|
||||
|
||||
defm SLLX : F3_S<"sllx", 0b100101, 1, shl, i64, I64Regs>;
|
||||
defm SRLX : F3_S<"srlx", 0b100110, 1, srl, i64, I64Regs>;
|
||||
defm SRAX : F3_S<"srax", 0b100111, 1, sra, i64, I64Regs>;
|
||||
|
||||
} // Predicates = [Is64Bit]
|
@ -111,4 +111,41 @@ class F3_3<bits<2> opVal, bits<6> op3val, bits<9> opfval, dag outs, dag ins,
|
||||
let Inst{4-0} = rs2;
|
||||
}
|
||||
|
||||
// Shift by register rs2.
|
||||
class F3_Sr<bits<2> opVal, bits<6> op3val, bit xVal, dag outs, dag ins,
|
||||
string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
|
||||
bit x = xVal; // 1 for 64-bit shifts.
|
||||
bits<5> rs2;
|
||||
|
||||
let op = opVal;
|
||||
let op3 = op3val;
|
||||
|
||||
let Inst{13} = 0; // i field = 0
|
||||
let Inst{12} = x; // extended registers.
|
||||
let Inst{4-0} = rs2;
|
||||
}
|
||||
|
||||
// Shift by immediate.
|
||||
class F3_Si<bits<2> opVal, bits<6> op3val, bit xVal, dag outs, dag ins,
|
||||
string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
|
||||
bit x = xVal; // 1 for 64-bit shifts.
|
||||
bits<6> shcnt; // shcnt32 / shcnt64.
|
||||
|
||||
let op = opVal;
|
||||
let op3 = op3val;
|
||||
|
||||
let Inst{13} = 1; // i field = 1
|
||||
let Inst{12} = x; // extended registers.
|
||||
let Inst{5-0} = shcnt;
|
||||
}
|
||||
|
||||
// Define rr and ri shift instructions with patterns.
|
||||
multiclass F3_S<string OpcStr, bits<6> Op3Val, bit XVal, SDNode OpNode,
|
||||
ValueType VT, RegisterClass RC> {
|
||||
def rr : F3_Sr<2, Op3Val, XVal, (outs RC:$rd), (ins RC:$rs, RC:$rs2),
|
||||
!strconcat(OpcStr, " $rs, $rs2, $rd"),
|
||||
[(set VT:$rd, (OpNode VT:$rs, VT:$rs2))]>;
|
||||
def ri : F3_Si<2, Op3Val, XVal, (outs RC:$rd), (ins RC:$rs, unknown:$shcnt),
|
||||
!strconcat(OpcStr, " $rs, $shcnt, $rd"),
|
||||
[(set VT:$rd, (OpNode VT:$rs, (VT imm:$shcnt)))]>;
|
||||
}
|
||||
|
@ -816,3 +816,5 @@ def : Pat<(i32 (extloadi16 ADDRri:$src)), (LDUHri ADDRri:$src)>;
|
||||
// zextload bool -> zextload byte
|
||||
def : Pat<(i32 (zextloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>;
|
||||
def : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>;
|
||||
|
||||
include "SparcInstr64Bit.td"
|
||||
|
@ -5,3 +5,17 @@
|
||||
define i64 @ret2(i64 %a, i64 %b) {
|
||||
ret i64 %b
|
||||
}
|
||||
|
||||
; CHECK: shl_imm
|
||||
; CHECK: sllx %i0, 7, %i0
|
||||
define i64 @shl_imm(i64 %a) {
|
||||
%x = shl i64 %a, 7
|
||||
ret i64 %x
|
||||
}
|
||||
|
||||
; CHECK: sra_reg
|
||||
; CHECK: srax %i0, %i1, %i0
|
||||
define i64 @sra_reg(i64 %a, i64 %b) {
|
||||
%x = ashr i64 %a, %b
|
||||
ret i64 %x
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user