Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Add -mfix-imm48 option #32

Open
wants to merge 1 commit into
base: nanomips
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3487,6 +3487,8 @@ def mxgot : Flag<["-"], "mxgot">, Group<m_mips_Features_Group>;
def mno_xgot : Flag<["-"], "mno-xgot">, Group<m_mips_Features_Group>;
def mjump_table_opt : Flag<["-"], "mjump-table-opt">, Group<m_mips_Features_Group>;
def mno_jump_table_opt : Flag<["-"], "mno-jump-table-opt">, Group<m_mips_Features_Group>;
def mfix_nmips_hw110880 : Flag<["-"], "mfix-nmips-hw110880">, Group<m_mips_Features_Group>;
def mno_fix_nmips_hw110880 : Flag<["-"], "mno-fix-nmips-hw110880">, Group<m_mips_Features_Group>;
def mldc1_sdc1 : Flag<["-"], "mldc1-sdc1">, Group<m_mips_Features_Group>;
def mno_ldc1_sdc1 : Flag<["-"], "mno-ldc1-sdc1">, Group<m_mips_Features_Group>;
def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">,
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/Mips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,14 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
Features.push_back("-disable-jump-table-opt");
}

if (Arg *A = Args.getLastArg(options::OPT_mfix_nmips_hw110880,
options::OPT_mno_fix_nmips_hw110880)) {
if (A->getOption().matches(options::OPT_mfix_nmips_hw110880))
Features.push_back("+fix-hw110880");
else
Features.push_back("-fix-hw110880");
}

mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args, Triple);
if (FloatABI == mips::FloatABI::Soft) {
// FIXME: Note, this is a hack. We need to pass the selected float
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Driver/ToolChains/NanoMips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ void NanoMipsLinker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("--relax");
}

if (Args.hasFlag(options::OPT_mfix_nmips_hw110880,
options::OPT_mno_fix_nmips_hw110880, false)) {
CmdArgs.push_back("--fix-nmips-hw110880");
}

Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_u);

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/Mips/Mips.td
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ def FeatureUseIndirectJumpsHazard : SubtargetFeature<"use-indirect-jump-hazard",
"true", "Use indirect jump"
" guards to prevent certain speculation based attacks">;

def FeatureFixImm48 : SubtargetFeature<"fix-hw110880", "HasFixHw110880", "true", "Avoid problematic instructions for hw110880 issue">;

//===----------------------------------------------------------------------===//
// Register File, Calling Conv, Instruction Descriptions
//===----------------------------------------------------------------------===//
Expand Down
75 changes: 75 additions & 0 deletions llvm/lib/Target/Mips/MipsAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ using namespace llvm;

extern cl::opt<bool> EmitJalrReloc;

cl::opt<bool>
farazs-github marked this conversation as resolved.
Show resolved Hide resolved
FixHw110880("nmips-fix-hw110880", cl::Hidden,
cl::desc("nanoMIPS: Fix problematic instructions to avoid hw110880 issue"),
cl::init(true));

void MipsAsmPrinter::emitJumpTableInfo() {
if (!Subtarget->hasNanoMips() || Subtarget->useAbsoluteJumpTables() ) {
AsmPrinter::emitJumpTableInfo();
Expand Down Expand Up @@ -249,6 +254,56 @@ void MipsAsmPrinter::emitJumpTableDest(MCStreamer &OutStreamer,
EmitToStreamer(OutStreamer, LoadI);
}

bool MipsAsmPrinter::tryEmitHw110880Fix(MCStreamer &OutStreamer,
const MachineInstr *MI) {
if (!FixHw110880)
return false;

if (!Subtarget->hasFixHw110880())
return false;

if (MI->getOpcode() != Mips::Li_NM &&
MI->getOpcode() != Mips::ADDIU48_NM)
return false;

int LastOp = MI->getNumOperands() - 1;
auto Last = MI->getOperand(LastOp);

if (!Last.isImm())
return false;

int64_t Value = Last.getImm();

auto ImmValueNeedsHw110880Fix = [MI](int64_t Value) -> bool {
// Check if we are dealing with 48-bit LI
if ((MI->getOpcode() == Mips::Li_NM) &&
(isUInt<16>(Value) || isInt<9>(Value) || ((Value & 0xfffu) == 0u)))
return false;

return (((Value & 0x50016400) == 0x50012400) &&
(((Value >> 24) & 0x7) == 0x1 || ((Value >> 24) & 0x2) == 0x2));
};

if (!ImmValueNeedsHw110880Fix(Value))
return false;

MCSymbol *AbsZero = OutContext.getOrCreateSymbol(
Twine(getDataLayout().getPrivateGlobalPrefix()) +
Twine("zero"));

const MCExpr *ZeroRef = MCSymbolRefExpr::create(AbsZero, OutContext);
const MCExpr *ValueExpr = MCBinaryExpr::createAdd(
ZeroRef, MCConstantExpr::create(Value, OutContext, true, 4u), OutContext);

MCInst Load;
Load.setOpcode(MI->getOpcode());
for (int i = 0; i < LastOp; i++)
Load.addOperand(MCOperand::createReg(MI->getOperand(i).getReg()));
Load.addOperand(MCOperand::createExpr(ValueExpr));
EmitToStreamer(OutStreamer, Load);
return true;
}

// Each table starts with the following directive:
//
// .jumptable esize, nsize [, unsigned]
Expand Down Expand Up @@ -417,6 +472,12 @@ void MipsAsmPrinter::emitInstruction(const MachineInstr *MI) {
continue;
}

if (Subtarget->hasNanoMips() &&
tryEmitHw110880Fix(*OutStreamer, &*I)) {
continue;
}


if (Subtarget->hasNanoMips() &&
(I->getOpcode() == Mips::LoadJumpTableOffset)) {
emitJumpTableDest(*OutStreamer, &*I);
Expand Down Expand Up @@ -1294,6 +1355,20 @@ void MipsAsmPrinter::EmitFPCallStub(
}

void MipsAsmPrinter::emitEndOfAsmFile(Module &M) {
if (Subtarget->hasNanoMips() && FixHw110880) {
SmallString<8> Name;
auto Symbols = OutContext.getSymbols();
MCSymbol *AbsZero = Symbols.lookup(
(Twine(getDataLayout().getPrivateGlobalPrefix()) + Twine("zero"))
.toStringRef(Name));

if (AbsZero) {
assert(!AbsZero->isDefined());
// Force assembler to use relocations via weak symbol
OutStreamer->emitSymbolAttribute(AbsZero, MCSymbolAttr::MCSA_Weak);
OutStreamer->emitAssignment(AbsZero, MCConstantExpr::create(0u, OutContext));
}
}
// Emit needed stubs
//
for (std::map<
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/Mips/MipsAsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {

void emitJumpTableDest(MCStreamer &OutStreamer, const MachineInstr *MI);

bool tryEmitHw110880Fix(MCStreamer &OutStreamer, const MachineInstr *MI);

// Emit brsc instruction followed by a label that will be used while creating
// offset expressions in jump table entries.
void emitBrsc(MCStreamer &OutStreamer, const MachineInstr *MI);
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/Mips/MipsSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
// Use linker relaxation
bool UseLinkerRelax = true;

bool HasFixHw110880 = false;

/// The minimum alignment known to hold of the stack frame on
/// entry to the function and which must be maintained by every function.
Align stackAlignment;
Expand Down Expand Up @@ -355,6 +357,8 @@ class MipsSubtarget : public MipsGenSubtargetInfo {

bool useLinkerRelax() const { return UseLinkerRelax; }

bool hasFixHw110880() const { return HasFixHw110880; }

bool enableLongBranchPass() const {
return hasStandardEncoding() || inMicroMipsMode() || allowMixed16_32();
}
Expand Down
27 changes: 17 additions & 10 deletions llvm/test/CodeGen/Mips/nanomips/addiu.ll
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
; RUN: llc -mtriple=nanomips -asm-show-inst -verify-machineinstrs < %s | FileCheck %s

; RUN: llc -mtriple=nanomips -asm-show-inst -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-ALL --check-prefix=CHECK %s
; RUN: llc -mtriple=nanomips -asm-show-inst -mattr=+fix-hw110880 -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-ALL --check-prefix=CHECK-FIX %s
define i32 @test_addiu0(i32 %a) {
; CHECK: addiu $a0, $a0, 1
; CHECK-ALL: addiu $a0, $a0, 1
%added = add i32 %a, 1
ret i32 %added
}

define i32 @test_addiu1(i32 %a) {
; CHECK: addiu $a0, $a0, 65535
; CHECK-ALL: addiu $a0, $a0, 65535
%added = add i32 %a, 65535
ret i32 %added
}
Expand All @@ -19,7 +19,7 @@ define i32 @test_addiu2(i32 %a) {
}

define i32 @test_addiu3(i32 %a) {
; CHECK: addiu $a0, $a0, -2048
; CHECK-ALL: addiu $a0, $a0, -2048
%added = add i32 %a, -2048
ret i32 %added
}
Expand All @@ -31,26 +31,33 @@ define i32 @test_addiu4(i32 %a) {
}

define i32 @test_addiu5(i32 %a) {
; CHECK: addiu[48] $a0, $a0, 2147483647
; CHECK-ALL: addiu[48] $a0, $a0, 2147483647
%added = add i32 %a, 2147483647
ret i32 %added
}

define i32 @test_addiu6(i32 %a) {
; CHECK: addiu[48] $a0, $a0, -2147483648
; CHECK-ALL: addiu[48] $a0, $a0, -2147483648
%added = add i32 %a, -2147483648
ret i32 %added
}

define i32 @test_addiu7(i32 %a, i32 %b) {
; CHECK: move $a0, $a1
; CHECK: addiu[48] $a0, $a0, -2049
; CHECK-ALL: move $a0, $a1
; CHECK-ALL: addiu[48] $a0, $a0, -2049
%added = add i32 %b, -2049
ret i32 %added
}

define i32 @test_addiu8(i32 %a) {
; CHECK: addiu[48] $a0, $a0, -2147483648
; CHECK-ALL: addiu[48] $a0, $a0, -2147483648
%added = add i32 %a, 2147483648
ret i32 %added
}

define i32 @test_addiu9(i32 %a) {
; CHECK: addiu[48] $a0, $a0, 1375806708
; CHECK-FIX: addiu[48] $a0, $a0, .Lzero+0x520124f4
%added = add i32 %a, 1375806708
ret i32 %added
}
32 changes: 25 additions & 7 deletions llvm/test/CodeGen/Mips/nanomips/li.ll
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
; RUN: llc -mtriple=nanomips -asm-show-inst -verify-machineinstrs < %s | FileCheck %s
; RUN: llc -mtriple=nanomips -asm-show-inst -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-ALL --check-prefix=CHECK %s
; RUN: llc -mtriple=nanomips -asm-show-inst -mattr=+fix-hw110880 -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-ALL --check-prefix=CHECK-FIX %s

define i32 @foo0() nounwind readnone {
; CHECK-LABEL: foo0
entry:
; CHECK: li $a0, 12345
; CHECK: Li_NM
; CHECK-ALL: li $a0, 12345
; CHECK-ALL: Li_NM
ret i32 12345
}

define i32 @foo1() nounwind readnone {
; CHECK-LABEL: foo1
entry:
; CHECK: li $a0, -2147483648
; CHECK: Li_NM
; CHECK-ALL: li $a0, -2147483648
; CHECK-ALL: Li_NM
ret i32 -2147483648
}

define i32 @foo2() nounwind readnone {
; CHECK-LABEL: foo2
entry:
; CHECK: li $a0, 2147483647
; CHECK: Li_NM
; CHECK-ALL: li $a0, 2147483647
; CHECK-ALL: Li_NM
ret i32 2147483647
}

define i32 @foo3() nounwind readnone {
; CHECK-LABEL: foo3
entry:
; CHECK-ALL: li $a0, 2147479552
; CHECK-ALL: Li_NM
ret i32 2147479552
}

define i32 @foo4() nounwind readnone {
; CHECK-LABEL: foo4
entry:
; CHECK: li $a0, 1375806708
; CHECK-FIX: li $a0, .Lzero+0x520124f4
; CHECK-ALL: Li_NM
ret i32 1375806708
}
Loading