Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
24 changes: 20 additions & 4 deletions llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaDisassembler() {
createXtensaDisassembler);
}

const unsigned ARDecoderTable[] = {
const MCPhysReg ARDecoderTable[] = {
Xtensa::A0, Xtensa::SP, Xtensa::A2, Xtensa::A3, Xtensa::A4, Xtensa::A5,
Xtensa::A6, Xtensa::A7, Xtensa::A8, Xtensa::A9, Xtensa::A10, Xtensa::A11,
Xtensa::A12, Xtensa::A13, Xtensa::A14, Xtensa::A15};
Expand All @@ -68,12 +68,12 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
if (RegNo >= std::size(ARDecoderTable))
return MCDisassembler::Fail;

unsigned Reg = ARDecoderTable[RegNo];
MCPhysReg Reg = ARDecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}

const unsigned SRDecoderTable[] = {
const MCPhysReg SRDecoderTable[] = {
Xtensa::SAR, 3, Xtensa::WINDOWBASE, 72, Xtensa::WINDOWSTART, 73};

static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
Expand All @@ -84,7 +84,7 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,

for (unsigned i = 0; i < std::size(SRDecoderTable); i += 2) {
if (SRDecoderTable[i + 1] == RegNo) {
unsigned Reg = SRDecoderTable[i];
MCPhysReg Reg = SRDecoderTable[i];

if (!Xtensa::checkRegister(Reg,
Decoder->getSubtargetInfo().getFeatureBits()))
Expand All @@ -98,6 +98,22 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
return MCDisassembler::Fail;
}

const MCPhysReg BRDecoderTable[] = {
Xtensa::B0, Xtensa::B1, Xtensa::B2, Xtensa::B3, Xtensa::B4, Xtensa::B5,
Xtensa::B6, Xtensa::B7, Xtensa::B8, Xtensa::B9, Xtensa::B10, Xtensa::B11,
Xtensa::B12, Xtensa::B13, Xtensa::B14, Xtensa::B15};

static DecodeStatus DecodeBRRegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo >= std::size(BRDecoderTable))
return MCDisassembler::Fail;

MCPhysReg Reg = BRDecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}

static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
uint64_t Address, uint64_t Offset,
uint64_t InstSize, MCInst &MI,
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ bool Xtensa::isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset) {
// Verify Special Register
bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
switch (RegNo) {
case Xtensa::BREG:
return FeatureBits[Xtensa::FeatureBoolean];
case Xtensa::WINDOWBASE:
case Xtensa::WINDOWSTART:
return FeatureBits[Xtensa::FeatureWindowed];
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ def FeatureWindowed : SubtargetFeature<"windowed", "HasWindowed", "true",
"Enable Xtensa Windowed Register option">;
def HasWindowed : Predicate<"Subtarget->hasWindowed()">,
AssemblerPredicate<(all_of FeatureWindowed)>;

def FeatureBoolean : SubtargetFeature<"bool", "HasBoolean", "true",
"Enable Xtensa Boolean extension">;
def HasBoolean : Predicate<"Subtarget->hasBoolean()">,
AssemblerPredicate<(all_of FeatureBoolean)>;
4 changes: 4 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
// Set up the register classes.
addRegisterClass(MVT::i32, &Xtensa::ARRegClass);

if (Subtarget.hasBoolean()) {
addRegisterClass(MVT::v1i1, &Xtensa::BRRegClass);
}

// Set up special registers.
setStackPointerRegisterToSaveRestore(Xtensa::SP);

Expand Down
70 changes: 70 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -779,3 +779,73 @@ def ROTW : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins imm8n_7:$imm),
let s = 0x0;
let t = imm{3-0};
}

//===----------------------------------------------------------------------===//
// Boolean Instructions
//===----------------------------------------------------------------------===//

def ALL4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
"all4\t$t, $s", []>, Requires<[HasBoolean]> {
let r = 0x9;
}

def ALL8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
"all8\t$t, $s", []>, Requires<[HasBoolean]> {
let r = 0xB;
}

def ANDB : RRR_Inst<0x00, 0x02, 0x00, (outs BR:$r), (ins BR:$s, BR:$t),
"andb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
def ANDBC : RRR_Inst<0x00, 0x02, 0x01, (outs BR:$r), (ins BR:$s, BR:$t),
"andbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
def ORB : RRR_Inst<0x00, 0x02, 0x02, (outs BR:$r), (ins BR:$s, BR:$t),
"orb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
def ORBC : RRR_Inst<0x00, 0x02, 0x03, (outs BR:$r), (ins BR:$s, BR:$t),
"orbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
def XORB : RRR_Inst<0x00, 0x02, 0x04, (outs BR:$r), (ins BR:$s, BR:$t),
"xorb\t$r, $s, $t", []>, Requires<[HasBoolean]>;

def ANY4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
"any4\t$t, $s", []>, Requires<[HasBoolean]> {
let r = 0x8;
}

def ANY8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
"any8\t$t, $s", []>, Requires<[HasBoolean]> {
let r = 0xA;
}

let isBranch = 1, isTerminator = 1, Predicates = [HasBoolean] in {
def BT : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target),
"bt\t$b, $target", []> {
bits<8> target;
bits<4> b;

let r = 0x1;
let s = b;
let t = 0x7;
let imm8 = target;
}

def BF : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target),
"bf\t$b, $target", []> {
bits<8> target;
bits<4> b;

let r = 0x0;
let s = b;
let t = 0x7;
let imm8 = target;
}
}

def : InstAlias<"_BT\t$b, $target", (BT BR:$b, brtarget:$target)>;
def : InstAlias<"_BF\t$b, $target", (BF BR:$b, brtarget:$target)>;

let Constraints = "$dr = $r,@earlyclobber $dr" in {
def MOVF : RRR_Inst<0x00, 0x03, 0x0C, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
"movf\t$r, $s, $t", []>, Requires<[HasBoolean]>;

def MOVT : RRR_Inst<0x00, 0x03, 0x0D, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
"movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
}
24 changes: 23 additions & 1 deletion llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def A15 : ARReg<15, "a15">, DwarfRegNum<[15]>;
def AR : RegisterClass<"Xtensa", [i32], 32, (add
A8, A9, A10, A11, A12, A13, A14, A15,
A7, A6, A5, A4, A3, A2, A0, SP)>;

//===----------------------------------------------------------------------===//
// Special-purpose registers
//===----------------------------------------------------------------------===//
Expand All @@ -75,8 +76,29 @@ class SRReg<bits<8> num, string n, list<string> alt = []> : XtensaReg<n> {
// Shift Amount Register
def SAR : SRReg<3, "sar", ["SAR","3"]>;

// Boolean Register
def BREG : SRReg<4, "br", ["BR","4"]>;

// Windowed Register Option registers
def WINDOWBASE : SRReg<72, "windowbase", ["WINDOWBASE", "72"]>;
def WINDOWSTART : SRReg<73, "windowstart", ["WINDOWSTART", "73"]>;

def SR : RegisterClass<"Xtensa", [i32], 32, (add SAR, WINDOWBASE, WINDOWSTART)>;
def SR : RegisterClass<"Xtensa", [i32], 32, (add SAR, BREG,
WINDOWBASE, WINDOWSTART)>;

//===----------------------------------------------------------------------===//
// Boolean registers
//===----------------------------------------------------------------------===//
class BReg<bits<4> num, string n> : XtensaReg<n> {
let HWEncoding{3-0} = num;
}

foreach i = 0-15 in {
def B#i : BReg<i, "b"#i>;
}

// Boolean register class
def BR : RegisterClass<"Xtensa", [v1i1], 8, (add B0, B1,
B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15)> {
let Size = 8;
}
2 changes: 0 additions & 2 deletions llvm/lib/Target/Xtensa/XtensaSubtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ XtensaSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) {
CPUName = "generic";
}

HasDensity = false;

// Parse features string.
ParseSubtargetFeatures(CPUName, CPUName, FS);
return *this;
Expand Down
11 changes: 6 additions & 5 deletions llvm/lib/Target/Xtensa/XtensaSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
SelectionDAGTargetInfo TSInfo;
XtensaFrameLowering FrameLowering;

// Enabled Xtensa Density Option
bool HasDensity;

// Enabled Xtensa Windowed Register Option
bool HasWindowed;
// Bool members corresponding to the SubtargetFeatures defined in tablegen
#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
bool ATTRIBUTE = DEFAULT;
#include "XtensaGenSubtargetInfo.inc"

XtensaSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);

Expand Down Expand Up @@ -69,6 +68,8 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {

bool hasWindowed() const { return HasWindowed; }

bool hasBoolean() const { return HasBoolean; }

// Automatically generated by tblgen.
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
};
Expand Down
59 changes: 59 additions & 0 deletions llvm/test/MC/Disassembler/Xtensa/boolean.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
# RUN: llvm-mc -triple=xtensa -mattr=+bool -disassemble %s | FileCheck -check-prefixes=CHECK-BOOLEAN %s
# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s

## Verify that binary code is correctly disassembled with
## boolean option enabled. Also verify that dissasembling without
## boolean option generates warnings.

[0x10,0x94,0x00]
# CHECK-BOOLEAN: all4 b1, b4
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x10,0xb8,0x00]
# CHECK-BOOLEAN: all8 b1, b8
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x30,0x12,0x02]
# CHECK-BOOLEAN: andb b1, b2, b3
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x30,0x12,0x12]
# CHECK-BOOLEAN: andbc b1, b2, b3
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x30,0x12,0x22]
# CHECK-BOOLEAN: orb b1, b2, b3
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x30,0x12,0x32]
# CHECK-BOOLEAN: orbc b1, b2, b3
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x30,0x12,0x42]
# CHECK-BOOLEAN: xorb b1, b2, b3
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x10,0x84,0x00]
# CHECK-BOOLEAN: any4 b1, b4
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x10,0xa8,0x00]
# CHECK-BOOLEAN: any8 b1, b8
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x76,0x11,0x10]
# CHECK-BOOLEAN: bt b1, . +20
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x76,0x00,0x10]
# CHECK-BOOLEAN: bf b0, . +20
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x10,0x23,0xc3]
# CHECK-BOOLEAN: movf a2, a3, b1
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding

[0x20,0x34,0xd3]
# CHECK-BOOLEAN: movt a3, a4, b2
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
58 changes: 58 additions & 0 deletions llvm/test/MC/Xtensa/boolean.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+bool \
# RUN: | FileCheck -check-prefixes=CHECK %s

.align 4
// CHECK: .p2align 4

LBL0:
// CHECK: LBL0:

all4 b1, b4
// CHECK: all4 b1, b4 # encoding: [0x10,0x94,0x00]

all8 b1, b8
// CHECK: all8 b1, b8 # encoding: [0x10,0xb8,0x00]

andb b1, b2, b3
// CHECK: andb b1, b2, b3 # encoding: [0x30,0x12,0x02]

andbc b1, b2, b3
// CHECK: andbc b1, b2, b3 # encoding: [0x30,0x12,0x12]

orb b1, b2, b3
// CHECK: orb b1, b2, b3 # encoding: [0x30,0x12,0x22]

orbc b1, b2, b3
// CHECK: orbc b1, b2, b3 # encoding: [0x30,0x12,0x32]

xorb b1, b2, b3
// CHECK: xorb b1, b2, b3 # encoding: [0x30,0x12,0x42]

any4 b1, b4
// CHECK: any4 b1, b4 # encoding: [0x10,0x84,0x00]

any8 b1, b8
// CHECK: any8 b1, b8 # encoding: [0x10,0xa8,0x00]

bt b1, LBL0
// CHECK: bt b1, LBL0 # encoding: [0x76,0x11,A]
// CHECK-NEXT: # fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_8

bf b0, LBL0
// CHECK: bf b0, LBL0 # encoding: [0x76,0x00,A]
// CHECK-NEXT: # fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_8

movf a2, a3, b1
// CHECK: movf a2, a3, b1 # encoding: [0x10,0x23,0xc3]

movt a3, a4, b2
// CHECK: movt a3, a4, b2 # encoding: [0x20,0x34,0xd3]

xsr a3, br
// CHECK: xsr a3, br # encoding: [0x30,0x04,0x61]

xsr.br a3
// CHECK: xsr a3, br # encoding: [0x30,0x04,0x61]

xsr a3, 4
// CHECK: xsr a3, br # encoding: [0x30,0x04,0x61]