#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MathExtras.h"
using namespace llvm;
// Prepare value for the target space for it
-static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
+static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
+ MCContext *Ctx = NULL) {
+
+ unsigned Kind = Fixup.getKind();
// Add/subtract and shift
switch (Kind) {
// so the displacement will be one instruction size less.
Value -= 4;
// The displacement is then divided by 4 to give us an 18 bit
- // address range.
- Value >>= 2;
+ // address range. Forcing a signed division because Value can be negative.
+ Value = (int64_t)Value / 4;
+ // We now check if Value can be encoded as a 16-bit signed immediate.
+ if (!isIntN(15, Value) && Ctx)
+ Ctx->FatalError(Fixup.getLoc(), "out of range PC16 fixup");
break;
case Mips::fixup_Mips_26:
// So far we are only using this type for jumps.
break;
case Mips::fixup_MICROMIPS_PC16_S1:
Value -= 4;
- Value >>= 1;
+ // Forcing a signed division because Value can be negative.
+ Value = (int64_t)Value / 2;
+ // We now check if Value can be encoded as a 16-bit signed immediate.
+ if (!isIntN(15, Value) && Ctx)
+ Ctx->FatalError(Fixup.getLoc(), "out of range PC16 fixup");
break;
}
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
uint64_t Value) const {
MCFixupKind Kind = Fixup.getKind();
- Value = adjustFixupValue((unsigned)Kind, Value);
+ Value = adjustFixupValue(Fixup, Value);
if (!Value)
return; // Doesn't change encoding.
OW->Write32(0);
return true;
}
+
+ /// processFixupValue - Target hook to process the literal value of a fixup
+ /// if necessary.
+ void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFixup &Fixup, const MCFragment *DF,
+ MCValue &Target, uint64_t &Value,
+ bool &IsResolved) {
+ // At this point we'll ignore the value returned by adjustFixupValue as
+ // we are only checking if the fixup can be applied correctly. We have
+ // access to MCContext from here which allows us to report a fatal error
+ // with *possibly* a source code location.
+ (void)adjustFixupValue(Fixup, Value, &Asm.getContext());
+ }
+
}; // class MipsAsmBackend
} // namespace
--- /dev/null
+# RUN: not llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -mattr=+msa -arch=mips -mattr=+micromips 2>&1 | FileCheck %s
+#
+# CHECK: error: branch to misaligned address
+# CHECK: b -65535
+# CHECK: error: branch target out of range
+# CHECK: b -65537
+# CHECK: error: branch to misaligned address
+# CHECK: b 65535
+# CHECK: error: branch target out of range
+# CHECK: b 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: beq $1, $1, -65535
+# CHECK: error: branch target out of range
+# CHECK: beq $1, $1, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: beq $1, $1, 65535
+# CHECK: error: branch target out of range
+# CHECK: beq $1, $1, 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bne $1, $1, -65535
+# CHECK: error: branch target out of range
+# CHECK: bne $1, $1, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bne $1, $1, 65535
+# CHECK: error: branch target out of range
+# CHECK: bne $1, $1, 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bal -65535
+# CHECK: error: branch target out of range
+# CHECK: bal -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bal 65535
+# CHECK: error: branch target out of range
+# CHECK: bal 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bgez $1, -65535
+# CHECK: error: branch target out of range
+# CHECK: bgez $1, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bgez $1, 65535
+# CHECK: error: branch target out of range
+# CHECK: bgez $1, 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bgtz $1, -65535
+# CHECK: error: branch target out of range
+# CHECK: bgtz $1, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bgtz $1, 65535
+# CHECK: error: branch target out of range
+# CHECK: bgtz $1, 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: blez $1, -65535
+# CHECK: error: branch target out of range
+# CHECK: blez $1, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: blez $1, 65535
+# CHECK: error: branch target out of range
+# CHECK: blez $1, 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bltz $1, -65535
+# CHECK: error: branch target out of range
+# CHECK: bltz $1, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bltz $1, 65535
+# CHECK: error: branch target out of range
+# CHECK: bltz $1, 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bgezal $1, -65535
+# CHECK: error: branch target out of range
+# CHECK: bgezal $1, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bgezal $1, 65535
+# CHECK: error: branch target out of range
+# CHECK: bgezal $1, 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bltzal $1, -65535
+# CHECK: error: branch target out of range
+# CHECK: bltzal $1, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bltzal $1, 65535
+# CHECK: error: branch target out of range
+# CHECK: bltzal $1, 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f -65535
+# CHECK: error: branch target out of range
+# CHECK: bc1f -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f 65535
+# CHECK: error: branch target out of range
+# CHECK: bc1f 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f $fcc0, -65535
+# CHECK: error: branch target out of range
+# CHECK: bc1f $fcc0, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f $fcc0, 65535
+# CHECK: error: branch target out of range
+# CHECK: bc1f $fcc0, 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t -65535
+# CHECK: error: branch target out of range
+# CHECK: bc1t -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t 65535
+# CHECK: error: branch target out of range
+# CHECK: bc1t 65536
+
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t $fcc0, -65535
+# CHECK: error: branch target out of range
+# CHECK: bc1t $fcc0, -65537
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t $fcc0, 65535
+# CHECK: error: branch target out of range
+# CHECK: bc1t $fcc0, 65536
+
+ b -65535
+ b -65536
+ b -65537
+ b 65534
+ b 65535
+ b 65536
+
+ beq $1, $1, -65535
+ beq $1, $1, -65536
+ beq $1, $1, -65537
+ beq $1, $1, 65534
+ beq $1, $1, 65535
+ beq $1, $1, 65536
+
+ bne $1, $1, -65535
+ bne $1, $1, -65536
+ bne $1, $1, -65537
+ bne $1, $1, 65534
+ bne $1, $1, 65535
+ bne $1, $1, 65536
+
+ bal -65535
+ bal -65536
+ bal -65537
+ bal 65534
+ bal 65535
+ bal 65536
+
+ bgez $1, -65535
+ bgez $1, -65536
+ bgez $1, -65537
+ bgez $1, 65534
+ bgez $1, 65535
+ bgez $1, 65536
+
+ bgtz $1, -65535
+ bgtz $1, -65536
+ bgtz $1, -65537
+ bgtz $1, 65534
+ bgtz $1, 65535
+ bgtz $1, 65536
+
+ blez $1, -65535
+ blez $1, -65536
+ blez $1, -65537
+ blez $1, 65534
+ blez $1, 65535
+ blez $1, 65536
+
+ bltz $1, -65535
+ bltz $1, -65536
+ bltz $1, -65537
+ bltz $1, 65534
+ bltz $1, 65535
+ bltz $1, 65536
+
+ bgezal $1, -65535
+ bgezal $1, -65536
+ bgezal $1, -65537
+ bgezal $1, 65534
+ bgezal $1, 65535
+ bgezal $1, 65536
+
+ bltzal $1, -65535
+ bltzal $1, -65536
+ bltzal $1, -65537
+ bltzal $1, 65534
+ bltzal $1, 65535
+ bltzal $1, 65536
+
+ bc1f -65535
+ bc1f -65536
+ bc1f -65537
+ bc1f 65534
+ bc1f 65535
+ bc1f 65536
+
+ bc1f $fcc0, -65535
+ bc1f $fcc0, -65536
+ bc1f $fcc0, -65537
+ bc1f $fcc0, 65534
+ bc1f $fcc0, 65535
+ bc1f $fcc0, 65536
+
+ bc1t -65535
+ bc1t -65536
+ bc1t -65537
+ bc1t 65534
+ bc1t 65535
+ bc1t 65536
+
+ bc1t $fcc0, -65535
+ bc1t $fcc0, -65536
+ bc1t $fcc0, -65537
+ bc1t $fcc0, 65534
+ bc1t $fcc0, 65535
+ bc1t $fcc0, 65536
--- /dev/null
+# RUN: not llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -arch=mips 2>&1 | FileCheck %s
+#
+# CHECK: error: branch to misaligned address
+# CHECK: b -131069
+# CHECK: error: branch to misaligned address
+# CHECK: b -131070
+# CHECK: error: branch to misaligned address
+# CHECK: b -131071
+# CHECK: error: branch target out of range
+# CHECK: b -131073
+# CHECK: error: branch to misaligned address
+# CHECK: b 131069
+# CHECK: error: branch to misaligned address
+# CHECK: b 131070
+# CHECK: error: branch to misaligned address
+# CHECK: b 131071
+# CHECK: error: branch target out of range
+# CHECK: b 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: beq $1, $1, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: beq $1, $1, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: beq $1, $1, -131071
+# CHECK: error: branch target out of range
+# CHECK: beq $1, $1, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: beq $1, $1, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: beq $1, $1, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: beq $1, $1, 131071
+# CHECK: error: branch target out of range
+# CHECK: beq $1, $1, 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bne $1, $1, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bne $1, $1, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bne $1, $1, -131071
+# CHECK: error: branch target out of range
+# CHECK: bne $1, $1, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bne $1, $1, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bne $1, $1, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bne $1, $1, 131071
+# CHECK: error: branch target out of range
+# CHECK: bne $1, $1, 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bal -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bal -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bal -131071
+# CHECK: error: branch target out of range
+# CHECK: bal -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bal 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bal 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bal 131071
+# CHECK: error: branch target out of range
+# CHECK: bal 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bgez $1, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bgez $1, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bgez $1, -131071
+# CHECK: error: branch target out of range
+# CHECK: bgez $1, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bgez $1, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bgez $1, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bgez $1, 131071
+# CHECK: error: branch target out of range
+# CHECK: bgez $1, 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bgtz $1, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bgtz $1, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bgtz $1, -131071
+# CHECK: error: branch target out of range
+# CHECK: bgtz $1, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bgtz $1, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bgtz $1, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bgtz $1, 131071
+# CHECK: error: branch target out of range
+# CHECK: bgtz $1, 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: blez $1, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: blez $1, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: blez $1, -131071
+# CHECK: error: branch target out of range
+# CHECK: blez $1, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: blez $1, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: blez $1, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: blez $1, 131071
+# CHECK: error: branch target out of range
+# CHECK: blez $1, 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bltz $1, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bltz $1, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bltz $1, -131071
+# CHECK: error: branch target out of range
+# CHECK: bltz $1, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bltz $1, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bltz $1, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bltz $1, 131071
+# CHECK: error: branch target out of range
+# CHECK: bltz $1, 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bgezal $1, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bgezal $1, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bgezal $1, -131071
+# CHECK: error: branch target out of range
+# CHECK: bgezal $1, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bgezal $1, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bgezal $1, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bgezal $1, 131071
+# CHECK: error: branch target out of range
+# CHECK: bgezal $1, 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bltzal $1, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bltzal $1, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bltzal $1, -131071
+# CHECK: error: branch target out of range
+# CHECK: bltzal $1, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bltzal $1, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bltzal $1, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bltzal $1, 131071
+# CHECK: error: branch target out of range
+# CHECK: bltzal $1, 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f -131071
+# CHECK: error: branch target out of range
+# CHECK: bc1f -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f 131071
+# CHECK: error: branch target out of range
+# CHECK: bc1f 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f $fcc0, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f $fcc0, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f $fcc0, -131071
+# CHECK: error: branch target out of range
+# CHECK: bc1f $fcc0, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f $fcc0, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f $fcc0, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bc1f $fcc0, 131071
+# CHECK: error: branch target out of range
+# CHECK: bc1f $fcc0, 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t -131071
+# CHECK: error: branch target out of range
+# CHECK: bc1t -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t 131071
+# CHECK: error: branch target out of range
+# CHECK: bc1t 131072
+
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t $fcc0, -131069
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t $fcc0, -131070
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t $fcc0, -131071
+# CHECK: error: branch target out of range
+# CHECK: bc1t $fcc0, -131073
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t $fcc0, 131069
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t $fcc0, 131070
+# CHECK: error: branch to misaligned address
+# CHECK: bc1t $fcc0, 131071
+# CHECK: error: branch target out of range
+# CHECK: bc1t $fcc0, 131072
+
+.text
+.set noat
+ b -131068
+ b -131069
+ b -131070
+ b -131071
+ b -131072
+ b -131073
+ b 131068
+ b 131069
+ b 131070
+ b 131071
+ b 131072
+
+ beq $1, $1, -131068
+ beq $1, $1, -131069
+ beq $1, $1, -131070
+ beq $1, $1, -131071
+ beq $1, $1, -131072
+ beq $1, $1, -131073
+ beq $1, $1, 131068
+ beq $1, $1, 131069
+ beq $1, $1, 131070
+ beq $1, $1, 131071
+ beq $1, $1, 131072
+
+ bne $1, $1, -131068
+ bne $1, $1, -131069
+ bne $1, $1, -131070
+ bne $1, $1, -131071
+ bne $1, $1, -131072
+ bne $1, $1, -131073
+ bne $1, $1, 131068
+ bne $1, $1, 131069
+ bne $1, $1, 131070
+ bne $1, $1, 131071
+ bne $1, $1, 131072
+
+ bal -131068
+ bal -131069
+ bal -131070
+ bal -131071
+ bal -131072
+ bal -131073
+ bal 131068
+ bal 131069
+ bal 131070
+ bal 131071
+ bal 131072
+
+ bgez $1, -131068
+ bgez $1, -131069
+ bgez $1, -131070
+ bgez $1, -131071
+ bgez $1, -131072
+ bgez $1, -131073
+ bgez $1, 131068
+ bgez $1, 131069
+ bgez $1, 131070
+ bgez $1, 131071
+ bgez $1, 131072
+
+ bgtz $1, -131068
+ bgtz $1, -131069
+ bgtz $1, -131070
+ bgtz $1, -131071
+ bgtz $1, -131072
+ bgtz $1, -131073
+ bgtz $1, 131068
+ bgtz $1, 131069
+ bgtz $1, 131070
+ bgtz $1, 131071
+ bgtz $1, 131072
+
+ blez $1, -131068
+ blez $1, -131069
+ blez $1, -131070
+ blez $1, -131071
+ blez $1, -131072
+ blez $1, -131073
+ blez $1, 131068
+ blez $1, 131069
+ blez $1, 131070
+ blez $1, 131071
+ blez $1, 131072
+
+ bltz $1, -131068
+ bltz $1, -131069
+ bltz $1, -131070
+ bltz $1, -131071
+ bltz $1, -131072
+ bltz $1, -131073
+ bltz $1, 131068
+ bltz $1, 131069
+ bltz $1, 131070
+ bltz $1, 131071
+ bltz $1, 131072
+
+ bgezal $1, -131068
+ bgezal $1, -131069
+ bgezal $1, -131070
+ bgezal $1, -131071
+ bgezal $1, -131072
+ bgezal $1, -131073
+ bgezal $1, 131068
+ bgezal $1, 131069
+ bgezal $1, 131070
+ bgezal $1, 131071
+ bgezal $1, 131072
+
+ bltzal $1, -131068
+ bltzal $1, -131069
+ bltzal $1, -131070
+ bltzal $1, -131071
+ bltzal $1, -131072
+ bltzal $1, -131073
+ bltzal $1, 131068
+ bltzal $1, 131069
+ bltzal $1, 131070
+ bltzal $1, 131071
+ bltzal $1, 131072
+
+ bc1f -131068
+ bc1f -131069
+ bc1f -131070
+ bc1f -131071
+ bc1f -131072
+ bc1f -131073
+ bc1f 131068
+ bc1f 131069
+ bc1f 131070
+ bc1f 131071
+ bc1f 131072
+
+ bc1f $fcc0, -131068
+ bc1f $fcc0, -131069
+ bc1f $fcc0, -131070
+ bc1f $fcc0, -131071
+ bc1f $fcc0, -131072
+ bc1f $fcc0, -131073
+ bc1f $fcc0, 131068
+ bc1f $fcc0, 131069
+ bc1f $fcc0, 131070
+ bc1f $fcc0, 131071
+ bc1f $fcc0, 131072
+
+ bc1t -131068
+ bc1t -131069
+ bc1t -131070
+ bc1t -131071
+ bc1t -131072
+ bc1t -131073
+ bc1t 131068
+ bc1t 131069
+ bc1t 131070
+ bc1t 131071
+ bc1t 131072
+
+ bc1t $fcc0, -131068
+ bc1t $fcc0, -131069
+ bc1t $fcc0, -131070
+ bc1t $fcc0, -131071
+ bc1t $fcc0, -131072
+ bc1t $fcc0, -131073
+ bc1t $fcc0, 131068
+ bc1t $fcc0, 131069
+ bc1t $fcc0, 131070
+ bc1t $fcc0, 131071
+ bc1t $fcc0, 131072