Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions llvm/lib/Target/Sparc/Sparc.td
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ def FeatureVIS2
def FeatureVIS3
: SubtargetFeature<"vis3", "IsVIS3", "true",
"Enable Visual Instruction Set extensions III">;
def FeatureUA2005
: SubtargetFeature<"ua2005", "IsUA2005", "true",
"Enable UltraSPARC Architecture 2005 extensions">;
def FeatureUA2007
: SubtargetFeature<"ua2007", "IsUA2007", "true",
"Enable UltraSPARC Architecture 2007 extensions">;
def FeatureLeon
: SubtargetFeature<"leon", "IsLeon", "true",
"Enable LEON extensions">;
Expand Down Expand Up @@ -152,13 +158,15 @@ def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated, FeatureVIS,
FeatureVIS2],
[TuneSlowRDPC]>;
def : Proc<"niagara", [FeatureV9, FeatureV8Deprecated, FeatureVIS,
FeatureVIS2]>;
FeatureVIS2, FeatureUA2005]>;
def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated, UsePopc,
FeatureVIS, FeatureVIS2]>;
FeatureVIS, FeatureVIS2, FeatureUA2005]>;
def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated, UsePopc,
FeatureVIS, FeatureVIS2]>;
FeatureVIS, FeatureVIS2, FeatureVIS3,
FeatureUA2005, FeatureUA2007]>;
def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated, UsePopc,
FeatureVIS, FeatureVIS2, FeatureVIS3]>;
FeatureVIS, FeatureVIS2, FeatureVIS3,
FeatureUA2005, FeatureUA2007]>;

// LEON 2 FT generic
def : Processor<"leon2", LEON2Itineraries,
Expand Down
30 changes: 3 additions & 27 deletions llvm/lib/Target/Sparc/SparcInstr64Bit.td
Original file line number Diff line number Diff line change
Expand Up @@ -180,37 +180,13 @@ def : Pat<(i64 (ctpop i64:$src)), (POPCrr $src)>;
//===----------------------------------------------------------------------===//

let Predicates = [Is64Bit] in {

def MULXrr : F3_1<2, 0b001001,
(outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2),
"mulx $rs1, $rs2, $rd",
[(set i64:$rd, (mul i64:$rs1, i64:$rs2))]>;
def MULXri : F3_2<2, 0b001001,
(outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$simm13),
"mulx $rs1, $simm13, $rd",
[(set i64:$rd, (mul i64:$rs1, (i64 simm13:$simm13)))]>;
defm MULX : F3_12<"mulx", 0b001001, mul, I64Regs, i64, i64imm>;

// Division can trap.
let hasSideEffects = 1 in {
def SDIVXrr : F3_1<2, 0b101101,
(outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2),
"sdivx $rs1, $rs2, $rd",
[(set i64:$rd, (sdiv i64:$rs1, i64:$rs2))]>;
def SDIVXri : F3_2<2, 0b101101,
(outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$simm13),
"sdivx $rs1, $simm13, $rd",
[(set i64:$rd, (sdiv i64:$rs1, (i64 simm13:$simm13)))]>;

def UDIVXrr : F3_1<2, 0b001101,
(outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2),
"udivx $rs1, $rs2, $rd",
[(set i64:$rd, (udiv i64:$rs1, i64:$rs2))]>;
def UDIVXri : F3_2<2, 0b001101,
(outs IntRegs:$rd), (ins IntRegs:$rs1, i64imm:$simm13),
"udivx $rs1, $simm13, $rd",
[(set i64:$rd, (udiv i64:$rs1, (i64 simm13:$simm13)))]>;
defm SDIVX : F3_12<"sdivx", 0b101101, sdiv, I64Regs, i64, i64imm>;
defm UDIVX : F3_12<"udivx", 0b001101, udiv, I64Regs, i64, i64imm>;
} // hasSideEffects = 1

} // Predicates = [Is64Bit]


Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/Sparc/SparcInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,23 @@ multiclass F3_S<string OpcStr, bits<6> Op3Val, bit XVal, SDNode OpNode,
itin>;
}

// 4-operand instructions.
class F3_4<bits<6> op3val, bits<4> op5val, dag outs, dag ins,
string asmstr, list<dag> pattern = [], InstrItinClass itin = NoItinerary>
: F3<outs, ins, asmstr, pattern, itin> {
bits<4> op5;
bits<5> rs3;
bits<5> rs2;

let op = 2;
let op3 = op3val;
let op5 = op5val;

let Inst{13-9} = rs3;
let Inst{8-5} = op5;
let Inst{4-0} = rs2;
}

class F4<bits<6> op3, dag outs, dag ins, string asmstr, list<dag> pattern,
InstrItinClass itin = NoItinerary>
: InstSP<outs, ins, asmstr, pattern, itin> {
Expand Down
41 changes: 25 additions & 16 deletions llvm/lib/Target/Sparc/SparcInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ def HasVIS2 : Predicate<"Subtarget->isVIS2()">,
def HasVIS3 : Predicate<"Subtarget->isVIS3()">,
AssemblerPredicate<(all_of FeatureVIS3)>;

// HasUA2005 - This is true when the target processor has UA 2005 extensions.
def HasUA2005 : Predicate<"Subtarget->isUA2005()">,
AssemblerPredicate<(all_of FeatureUA2005)>;

// HasUA2007 - This is true when the target processor has UA 2007 extensions.
def HasUA2007 : Predicate<"Subtarget->isUA2007()">,
AssemblerPredicate<(all_of FeatureUA2007)>;

// HasHardQuad - This is true when the target processor supports quad floating
// point instructions.
def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">;
Expand Down Expand Up @@ -467,22 +475,6 @@ multiclass LoadA<string OpcStr, bits<6> Op3Val, bits<6> LoadAOp3Val,
defm A : LoadASI<OpcStr, LoadAOp3Val, RC>;
}


// The LDSTUB instruction is supported for asm only.
// It is unlikely that general-purpose code could make use of it.
// CAS is preferred for sparc v9.
def LDSTUBrr : F3_1<3, 0b001101, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr),
"ldstub [$addr], $rd", []>;
def LDSTUBri : F3_2<3, 0b001101, (outs IntRegs:$rd), (ins (MEMri $rs1, $simm13):$addr),
"ldstub [$addr], $rd", []>;
def LDSTUBArr : F3_1_asi<3, 0b011101, (outs IntRegs:$rd),
(ins (MEMrr $rs1, $rs2):$addr, ASITag:$asi),
"ldstuba [$addr] $asi, $rd", []>;
let Predicates = [HasV9], Uses = [ASR3] in
def LDSTUBAri : F3_2<3, 0b011101, (outs IntRegs:$rd),
(ins (MEMri $rs1, $simm13):$addr),
"ldstuba [$addr] %asi, $rd", []>;

// Store multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot.
multiclass Store<string OpcStr, bits<6> Op3Val, SDPatternOperator OpNode,
RegisterClass RC, ValueType Ty, InstrItinClass itin = IIC_st> {
Expand Down Expand Up @@ -740,6 +732,22 @@ let rd = 1, mayStore = 1, Uses = [FSR] in {
"stx %fsr, [$addr]", []>, Requires<[HasV9]>;
}

// B.7. Atomic Load-Store Unsigned Byte Instructions
// (Atomic test-and-set)
// TODO look into the possibility to use this to implment `atomic_flag`.
// If it's possible, then LDSTUB is the preferred way to do it.
def LDSTUBrr : F3_1<3, 0b001101, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr),
"ldstub [$addr], $rd", []>;
def LDSTUBri : F3_2<3, 0b001101, (outs IntRegs:$rd), (ins (MEMri $rs1, $simm13):$addr),
"ldstub [$addr], $rd", []>;
def LDSTUBArr : F3_1_asi<3, 0b011101, (outs IntRegs:$rd),
(ins (MEMrr $rs1, $rs2):$addr, ASITag:$asi),
"ldstuba [$addr] $asi, $rd", []>;
let Predicates = [HasV9], Uses = [ASR3] in
def LDSTUBAri : F3_2<3, 0b011101, (outs IntRegs:$rd),
(ins (MEMri $rs1, $simm13):$addr),
"ldstuba [$addr] %asi, $rd", []>;

// Section B.8 - SWAP Register with Memory Instruction
// (Atomic swap)
let Constraints = "$val = $rd" in {
Expand Down Expand Up @@ -1968,4 +1976,5 @@ def : Pat<(build_vector (i32 IntRegs:$a1), (i32 IntRegs:$a2)),

include "SparcInstr64Bit.td"
include "SparcInstrVIS.td"
include "SparcInstrUAOSA.td"
include "SparcInstrAliases.td"
40 changes: 40 additions & 0 deletions llvm/lib/Target/Sparc/SparcInstrUAOSA.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===---- SparcInstrVIS.td - Visual Instruction Set extensions (VIS) -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains instruction formats, definitions and patterns needed for
// UA 2005 and UA 2007 instructions on SPARC.
//===----------------------------------------------------------------------===//

// Convenience template for 4-operand instructions
class FourOp<string OpcStr, bits<6> op3val, bits<4> op5val,
RegisterClass RC>
: F3_4<op3val, op5val, (outs RC:$rd), (ins RC:$rs1, RC:$rs2, RC:$rs3),
!strconcat(OpcStr, " $rs1, $rs2, $rs3, $rd")>;

// UltraSPARC Architecture 2005 Instructions
let Predicates = [HasUA2005] in {
let hasSideEffects = 1 in
def ALLCLEAN : InstSP<(outs), (ins), "allclean", []> {
let op = 2;
let Inst{29-19} = 0b00010110001;
let Inst{18-0} = 0;
}
} // Predicates = [HasUA2005]

// UltraSPARC Architecture 2007 Instructions
let Predicates = [HasUA2007] in {
def FMADDS : FourOp<"fmadds", 0b110111, 0b0001, FPRegs>;
def FMADDD : FourOp<"fmaddd", 0b110111, 0b0010, DFPRegs>;
def FMSUBS : FourOp<"fmsubs", 0b110111, 0b0101, FPRegs>;
def FMSUBD : FourOp<"fmsubd", 0b110111, 0b0110, DFPRegs>;

def FNMADDS : FourOp<"fnmadds", 0b110111, 0b1101, FPRegs>;
def FNMADDD : FourOp<"fnmaddd", 0b110111, 0b1110, DFPRegs>;
def FNMSUBS : FourOp<"fnmsubs", 0b110111, 0b1001, FPRegs>;
def FNMSUBD : FourOp<"fnmsubd", 0b110111, 0b1010, DFPRegs>;
} // Predicates = [HasUA2007]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are essentially VIS instructions, I would argue they should be placed in SparcInstrInfoVIS.td.

I'm not sure I understand the motivation for putting this handful of instructions into a separate file. What are the benefits?
They share encoding space with other related instructions, so it seems logical to me to put them together with those instructions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I basically go by how Sun/Oracle classifies the extensions, meaning that basically anything introduced in an ISA revision that isn't a VIS instruction go here.
In case of FMAf, it sits in the weird spot in that it's introduced between VIS2 and VIS3, and since Sun doesn't classify it as a VIS instruction, that's also the approach I took here.

This also goes for the one in the other PR, I suppose for crypto it makes sense to separate it out since it is tagged separately in the documentations, but for all others I think it's tidier if it's kept in this file?

25 changes: 25 additions & 0 deletions llvm/test/MC/Disassembler/Sparc/sparc-ua-osa.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# RUN: llvm-mc --disassemble %s -triple=sparcv9-unknown-linux -mattr=+ua2005,+ua2007 | FileCheck %s

## UA 2005 instructions.

# CHECK: allclean
0x85,0x88,0x00,0x00

## UA 2007 instructions.

# CHECK: fmadds %f1, %f3, %f5, %f7
0x8f,0xb8,0x4a,0x23
# CHECK: fmaddd %f0, %f2, %f4, %f6
0x8d,0xb8,0x08,0x42
# CHECK: fmsubs %f1, %f3, %f5, %f7
0x8f,0xb8,0x4a,0xa3
# CHECK: fmsubd %f0, %f2, %f4, %f6
0x8d,0xb8,0x08,0xc2
# CHECK: fnmadds %f1, %f3, %f5, %f7
0x8f,0xb8,0x4b,0xa3
# CHECK: fnmaddd %f0, %f2, %f4, %f6
0x8d,0xb8,0x09,0xc2
# CHECK: fnmsubs %f1, %f3, %f5, %f7
0x8f,0xb8,0x4b,0x23
# CHECK: fnmsubd %f0, %f2, %f4, %f6
0x8d,0xb8,0x09,0x42
8 changes: 8 additions & 0 deletions llvm/test/MC/Sparc/sparc-ua2005.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
! RUN: not llvm-mc %s -triple=sparcv9 -show-encoding 2>&1 | FileCheck %s --check-prefixes=NO-UA2005 --implicit-check-not=error:
! RUN: llvm-mc %s -triple=sparcv9 -mattr=+ua2005 -show-encoding | FileCheck %s --check-prefixes=UA2005

!! UA 2005 instructions.

! NO-UA2005: error: instruction requires a CPU feature not currently enabled
! UA2005: allclean ! encoding: [0x85,0x88,0x00,0x00]
allclean
30 changes: 30 additions & 0 deletions llvm/test/MC/Sparc/sparc-ua2007.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
! RUN: not llvm-mc %s -triple=sparcv9 -show-encoding 2>&1 | FileCheck %s --check-prefixes=NO-UA2007 --implicit-check-not=error:
! RUN: llvm-mc %s -triple=sparcv9 -mattr=+ua2007 -show-encoding | FileCheck %s --check-prefixes=UA2007

!! UA 2007 instructions.

! NO-UA2007: error: instruction requires a CPU feature not currently enabled
! UA2007: fmadds %f1, %f3, %f5, %f7 ! encoding: [0x8f,0xb8,0x4a,0x23]
fmadds %f1, %f3, %f5, %f7
! NO-UA2007: error: instruction requires a CPU feature not currently enabled
! UA2007: fmaddd %f0, %f2, %f4, %f6 ! encoding: [0x8d,0xb8,0x08,0x42]
fmaddd %f0, %f2, %f4, %f6
! NO-UA2007: error: instruction requires a CPU feature not currently enabled
! UA2007: fmsubs %f1, %f3, %f5, %f7 ! encoding: [0x8f,0xb8,0x4a,0xa3]
fmsubs %f1, %f3, %f5, %f7
! NO-UA2007: error: instruction requires a CPU feature not currently enabled
! UA2007: fmsubd %f0, %f2, %f4, %f6 ! encoding: [0x8d,0xb8,0x08,0xc2]
fmsubd %f0, %f2, %f4, %f6

! NO-UA2007: error: instruction requires a CPU feature not currently enabled
! UA2007: fnmadds %f1, %f3, %f5, %f7 ! encoding: [0x8f,0xb8,0x4b,0xa3]
fnmadds %f1, %f3, %f5, %f7
! NO-UA2007: error: instruction requires a CPU feature not currently enabled
! UA2007: fnmaddd %f0, %f2, %f4, %f6 ! encoding: [0x8d,0xb8,0x09,0xc2]
fnmaddd %f0, %f2, %f4, %f6
! NO-UA2007: error: instruction requires a CPU feature not currently enabled
! UA2007: fnmsubs %f1, %f3, %f5, %f7 ! encoding: [0x8f,0xb8,0x4b,0x23]
fnmsubs %f1, %f3, %f5, %f7
! NO-UA2007: error: instruction requires a CPU feature not currently enabled
! UA2007: fnmsubd %f0, %f2, %f4, %f6 ! encoding: [0x8d,0xb8,0x09,0x42]
fnmsubd %f0, %f2, %f4, %f6
Loading