Commit d00d48da by Reed Kotler Committed by Jan Voung

implement the null function for the Mips32 subzero compiler

BUG= https://code.google.com/p/nativeclient/issues/detail?id=4167 R=jvoung@chromium.org Review URL: https://codereview.chromium.org/1176133004 . Patch from Reed Kotler <reed.kotler@imgtec.com>.
parent 921856d4
...@@ -189,6 +189,7 @@ SRCS = \ ...@@ -189,6 +189,7 @@ SRCS = \
IceGlobalInits.cpp \ IceGlobalInits.cpp \
IceInst.cpp \ IceInst.cpp \
IceInstARM32.cpp \ IceInstARM32.cpp \
IceInstMIPS32.cpp \
IceInstX8632.cpp \ IceInstX8632.cpp \
IceIntrinsics.cpp \ IceIntrinsics.cpp \
IceLiveness.cpp \ IceLiveness.cpp \
......
...@@ -15,14 +15,18 @@ def TargetAssemblerFlags(target): ...@@ -15,14 +15,18 @@ def TargetAssemblerFlags(target):
# TODO(stichnot): -triple=i686-nacl should be used for a # TODO(stichnot): -triple=i686-nacl should be used for a
# sandboxing test. This means there should be an args.sandbox # sandboxing test. This means there should be an args.sandbox
# argument that also gets passed through to pnacl-sz. # argument that also gets passed through to pnacl-sz.
# TODO(reed kotler). Need to find out exactly we need to
# add here for Mips32.
flags = { 'x8632': ['-triple=i686'], flags = { 'x8632': ['-triple=i686'],
'arm32': ['-triple=armv7a', '-mcpu=cortex-a9', '-mattr=+neon'] } 'arm32': ['-triple=armv7a', '-mcpu=cortex-a9', '-mattr=+neon'],
'mips32': ['-triple=mipsel-none-nacl' ] }
return flags[target] return flags[target]
def TargetDisassemblerFlags(target): def TargetDisassemblerFlags(target):
flags = { 'x8632': ['-Mintel'], flags = { 'x8632': ['-Mintel'],
'arm32': [] } 'arm32': [],
'mips32':[] }
return flags[target] return flags[target]
...@@ -73,7 +77,7 @@ def main(): ...@@ -73,7 +77,7 @@ def main():
choices=['obj', 'asm', 'iasm'], choices=['obj', 'asm', 'iasm'],
help='Output file type. Default %(default)s.') help='Output file type. Default %(default)s.')
argparser.add_argument('--target', default='x8632', dest='target', argparser.add_argument('--target', default='x8632', dest='target',
choices=['x8632','arm32'], choices=['x8632','arm32','mips32'],
help='Target architecture. Default %(default)s.') help='Target architecture. Default %(default)s.')
argparser.add_argument('--echo-cmd', required=False, argparser.add_argument('--echo-cmd', required=False,
action='store_true', action='store_true',
......
...@@ -49,10 +49,12 @@ public: ...@@ -49,10 +49,12 @@ public:
SizeT getBundleAlignLog2Bytes() const override { return 4; } SizeT getBundleAlignLog2Bytes() const override { return 4; }
const char *getNonExecPadDirective() const override { return ".TBD"; } const char *getNonExecPadDirective() const override { return ".p2alignl"; }
llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override { llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override {
llvm::report_fatal_error("Not yet implemented."); // TODO(reed kotler) . Find out what this should be.
static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0};
return llvm::ArrayRef<uint8_t>(Padding, 4);
} }
void padWithNop(intptr_t Padding) override { void padWithNop(intptr_t Padding) override {
......
//===- subzero/src/IceInstMips32.cpp - Mips32 instruction implementation --===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
/// This file implements the InstMips32 and OperandMips32 classes,
/// primarily the constructors and the dump()/emit() methods.
///
//===----------------------------------------------------------------------===//
#include "IceAssemblerMIPS32.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceInst.h"
#include "IceInstMIPS32.h"
#include "IceOperand.h"
#include "IceRegistersMIPS32.h"
#include "IceTargetLoweringMIPS32.h"
namespace Ice {
InstMIPS32Ret::InstMIPS32Ret(Cfg *Func, Variable *RA, Variable *Source)
: InstMIPS32(Func, InstMIPS32::Ret, Source ? 2 : 1, nullptr) {
addSource(RA);
if (Source)
addSource(Source);
}
void InstMIPS32Ret::emit(const Cfg *Func) const {
if (!ALLOW_DUMP)
return;
assert(getSrcSize() > 0);
Variable *RA = llvm::cast<Variable>(getSrc(0));
assert(RA->hasReg());
assert(RA->getRegNum() == RegMIPS32::Reg_RA);
Ostream &Str = Func->getContext()->getStrEmit();
Str << "\t"
<< "jr $ra"
<< "\t";
RA->emit(Func);
}
void InstMIPS32Ret::emitIAS(const Cfg *Func) const {
(void)Func;
llvm_unreachable("Not yet implemented");
}
void InstMIPS32Ret::dump(const Cfg *Func) const {
if (!ALLOW_DUMP)
return;
Ostream &Str = Func->getContext()->getStrDump();
Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType());
Str << "ret." << Ty << " ";
dumpSources(Func);
}
}
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#define SUBZERO_SRC_ICEINSTMIPS32_DEF #define SUBZERO_SRC_ICEINSTMIPS32_DEF
// NOTE: PC and SP are not considered isInt, to avoid register allocating. // NOTE: PC and SP are not considered isInt, to avoid register allocating.
// TODO (reed kotler). This needs to be scrubbed and is a placeholder to get // TODO(reed kotler). This needs to be scrubbed and is a placeholder to get
// the Mips skeleton in. // the Mips skeleton in.
// //
#define REGMIPS32_GPR_TABLE \ #define REGMIPS32_GPR_TABLE \
......
...@@ -18,11 +18,64 @@ ...@@ -18,11 +18,64 @@
#define SUBZERO_SRC_ICEINSTMIPS32_H #define SUBZERO_SRC_ICEINSTMIPS32_H
#include "IceDefs.h" #include "IceDefs.h"
#include "IceInst.h"
#include "IceInstMIPS32.def"
#include "IceOperand.h"
namespace Ice { namespace Ice {
class TargetMIPS32; class TargetMIPS32;
// Fill this in.
/// Base class for Mips instructions.
class InstMIPS32 : public InstTarget {
InstMIPS32() = delete;
InstMIPS32(const InstMIPS32 &) = delete;
InstMIPS32 &operator=(const InstMIPS32 &) = delete;
public:
enum InstKindMIPS32 { k__Start = Inst::Target, Ret };
static const char *getWidthString(Type Ty);
void dump(const Cfg *Func) const override;
protected:
InstMIPS32(Cfg *Func, InstKindMIPS32 Kind, SizeT Maxsrcs, Variable *Dest)
: InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
~InstMIPS32() override {}
static bool isClassof(const Inst *Inst, InstKindMIPS32 MyKind) {
return Inst->getKind() == static_cast<InstKind>(MyKind);
}
};
/// Ret pseudo-instruction. This is actually a "jr" instruction with
/// an "ra" register operand, but epilogue lowering will search for a Ret
/// instead of a generic "jr". This instruction also takes a Source
/// operand (for non-void returning functions) for liveness analysis, though
/// a FakeUse before the ret would do just as well.
/// TODO(reed kotler): This needs was take from the ARM port and needs to be
/// scrubbed in the future.
class InstMIPS32Ret : public InstMIPS32 {
InstMIPS32Ret() = delete;
InstMIPS32Ret(const InstMIPS32Ret &) = delete;
InstMIPS32Ret &operator=(const InstMIPS32Ret &) = delete;
public:
static InstMIPS32Ret *create(Cfg *Func, Variable *RA,
Variable *Source = nullptr) {
return new (Func->allocate<InstMIPS32Ret>())
InstMIPS32Ret(Func, RA, Source);
}
void emit(const Cfg *Func) const override;
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override;
static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
private:
InstMIPS32Ret(Cfg *Func, Variable *RA, Variable *Source);
~InstMIPS32Ret() override {}
};
} // end of namespace Ice } // end of namespace Ice
......
...@@ -31,6 +31,17 @@ ...@@ -31,6 +31,17 @@
namespace Ice { namespace Ice {
namespace {
void UnimplementedError(const ClFlags &Flags) {
if (!Flags.getSkipUnimplemented()) {
// Use llvm_unreachable instead of report_fatal_error, which gives better
// stack traces.
llvm_unreachable("Not yet implemented");
abort();
}
}
} // end of anonymous namespace
TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) { TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {
// TODO: Don't initialize IntegerRegisters and friends every time. // TODO: Don't initialize IntegerRegisters and friends every time.
// Instead, initialize in some sort of static initializer for the // Instead, initialize in some sort of static initializer for the
...@@ -205,7 +216,8 @@ void TargetMIPS32::translateOm1() { ...@@ -205,7 +216,8 @@ void TargetMIPS32::translateOm1() {
bool TargetMIPS32::doBranchOpt(Inst *I, const CfgNode *NextNode) { bool TargetMIPS32::doBranchOpt(Inst *I, const CfgNode *NextNode) {
(void)I; (void)I;
(void)NextNode; (void)NextNode;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return false;
} }
IceString TargetMIPS32::RegNames[] = { IceString TargetMIPS32::RegNames[] = {
...@@ -247,23 +259,25 @@ void TargetMIPS32::emitVariable(const Variable *Var) const { ...@@ -247,23 +259,25 @@ void TargetMIPS32::emitVariable(const Variable *Var) const {
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
(void)Var; (void)Var;
(void)Str; (void)Str;
llvm::report_fatal_error("emitVariable: Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerArguments() { void TargetMIPS32::lowerArguments() {
llvm::report_fatal_error("lowerArguments: Not yet implemented"); VarList &Args = Func->getArgs();
if (Args.size() > 0)
UnimplementedError(Func->getContext()->getFlags());
} }
Type TargetMIPS32::stackSlotType() { return IceType_i32; } Type TargetMIPS32::stackSlotType() { return IceType_i32; }
void TargetMIPS32::addProlog(CfgNode *Node) { void TargetMIPS32::addProlog(CfgNode *Node) {
(void)Node; (void)Node;
llvm::report_fatal_error("addProlog: Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::addEpilog(CfgNode *Node) { void TargetMIPS32::addEpilog(CfgNode *Node) {
(void)Node; (void)Node;
llvm::report_fatal_error("addEpilog: Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
llvm::SmallBitVector TargetMIPS32::getRegisterSet(RegSetMask Include, llvm::SmallBitVector TargetMIPS32::getRegisterSet(RegSetMask Include,
...@@ -305,84 +319,84 @@ void TargetMIPS32::lowerAlloca(const InstAlloca *Inst) { ...@@ -305,84 +319,84 @@ void TargetMIPS32::lowerAlloca(const InstAlloca *Inst) {
// restriction can be relaxed in some cases. // restriction can be relaxed in some cases.
NeedsStackAlignment = true; NeedsStackAlignment = true;
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) {
switch (Inst->getOp()) { switch (Inst->getOp()) {
case InstArithmetic::_num: case InstArithmetic::_num:
llvm_unreachable("Unknown arithmetic operator"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Add: case InstArithmetic::Add:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::And: case InstArithmetic::And:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Or: case InstArithmetic::Or:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Xor: case InstArithmetic::Xor:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Sub: case InstArithmetic::Sub:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Mul: case InstArithmetic::Mul:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Shl: case InstArithmetic::Shl:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Lshr: case InstArithmetic::Lshr:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Ashr: case InstArithmetic::Ashr:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Udiv: case InstArithmetic::Udiv:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Sdiv: case InstArithmetic::Sdiv:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Urem: case InstArithmetic::Urem:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Srem: case InstArithmetic::Srem:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Fadd: case InstArithmetic::Fadd:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Fsub: case InstArithmetic::Fsub:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Fmul: case InstArithmetic::Fmul:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Fdiv: case InstArithmetic::Fdiv:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstArithmetic::Frem: case InstArithmetic::Frem:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
} }
} }
void TargetMIPS32::lowerAssign(const InstAssign *Inst) { void TargetMIPS32::lowerAssign(const InstAssign *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerBr(const InstBr *Inst) { void TargetMIPS32::lowerBr(const InstBr *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerCall(const InstCall *Inst) { void TargetMIPS32::lowerCall(const InstCall *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerCast(const InstCast *Inst) { void TargetMIPS32::lowerCast(const InstCast *Inst) {
...@@ -392,39 +406,39 @@ void TargetMIPS32::lowerCast(const InstCast *Inst) { ...@@ -392,39 +406,39 @@ void TargetMIPS32::lowerCast(const InstCast *Inst) {
Func->setError("Cast type not supported"); Func->setError("Cast type not supported");
return; return;
case InstCast::Sext: { case InstCast::Sext: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
} }
case InstCast::Zext: { case InstCast::Zext: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
} }
case InstCast::Trunc: { case InstCast::Trunc: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
} }
case InstCast::Fptrunc: case InstCast::Fptrunc:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstCast::Fpext: { case InstCast::Fpext: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
} }
case InstCast::Fptosi: case InstCast::Fptosi:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstCast::Fptoui: case InstCast::Fptoui:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstCast::Sitofp: case InstCast::Sitofp:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
case InstCast::Uitofp: { case InstCast::Uitofp: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
} }
case InstCast::Bitcast: { case InstCast::Bitcast: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
break; break;
} }
} }
...@@ -432,72 +446,72 @@ void TargetMIPS32::lowerCast(const InstCast *Inst) { ...@@ -432,72 +446,72 @@ void TargetMIPS32::lowerCast(const InstCast *Inst) {
void TargetMIPS32::lowerExtractElement(const InstExtractElement *Inst) { void TargetMIPS32::lowerExtractElement(const InstExtractElement *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerFcmp(const InstFcmp *Inst) { void TargetMIPS32::lowerFcmp(const InstFcmp *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerIcmp(const InstIcmp *Inst) { void TargetMIPS32::lowerIcmp(const InstIcmp *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerInsertElement(const InstInsertElement *Inst) { void TargetMIPS32::lowerInsertElement(const InstInsertElement *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
switch (Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID) { switch (Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID) {
case Intrinsics::AtomicCmpxchg: { case Intrinsics::AtomicCmpxchg: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::AtomicFence: case Intrinsics::AtomicFence:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
case Intrinsics::AtomicFenceAll: case Intrinsics::AtomicFenceAll:
// NOTE: FenceAll should prevent and load/store from being moved // NOTE: FenceAll should prevent and load/store from being moved
// across the fence (both atomic and non-atomic). The InstMIPS32Mfence // across the fence (both atomic and non-atomic). The InstMIPS32Mfence
// instruction is currently marked coarsely as "HasSideEffects". // instruction is currently marked coarsely as "HasSideEffects".
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
case Intrinsics::AtomicIsLockFree: { case Intrinsics::AtomicIsLockFree: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::AtomicLoad: { case Intrinsics::AtomicLoad: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::AtomicRMW: case Intrinsics::AtomicRMW:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
case Intrinsics::AtomicStore: { case Intrinsics::AtomicStore: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::Bswap: { case Intrinsics::Bswap: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::Ctpop: { case Intrinsics::Ctpop: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::Ctlz: { case Intrinsics::Ctlz: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::Cttz: { case Intrinsics::Cttz: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::Fabs: { case Intrinsics::Fabs: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::Longjmp: { case Intrinsics::Longjmp: {
...@@ -542,7 +556,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -542,7 +556,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
} }
case Intrinsics::NaClReadTP: { case Intrinsics::NaClReadTP: {
if (Ctx->getFlags().getUseSandboxing()) { if (Ctx->getFlags().getUseSandboxing()) {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} else { } else {
InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0); InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0);
lowerCall(Call); lowerCall(Call);
...@@ -556,19 +570,19 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -556,19 +570,19 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return; return;
} }
case Intrinsics::Sqrt: { case Intrinsics::Sqrt: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::Stacksave: { case Intrinsics::Stacksave: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::Stackrestore: { case Intrinsics::Stackrestore: {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
case Intrinsics::Trap: case Intrinsics::Trap:
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
return; return;
case Intrinsics::UnknownIntrinsic: case Intrinsics::UnknownIntrinsic:
Func->setError("Should not be lowering UnknownIntrinsic"); Func->setError("Should not be lowering UnknownIntrinsic");
...@@ -579,17 +593,17 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -579,17 +593,17 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
void TargetMIPS32::lowerLoad(const InstLoad *Inst) { void TargetMIPS32::lowerLoad(const InstLoad *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::doAddressOptLoad() { void TargetMIPS32::doAddressOptLoad() {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::randomlyInsertNop(float Probability) { void TargetMIPS32::randomlyInsertNop(float Probability) {
RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
if (RNG.getTrueWithProbability(Probability)) { if (RNG.getTrueWithProbability(Probability)) {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
} }
...@@ -598,31 +612,33 @@ void TargetMIPS32::lowerPhi(const InstPhi * /*Inst*/) { ...@@ -598,31 +612,33 @@ void TargetMIPS32::lowerPhi(const InstPhi * /*Inst*/) {
} }
void TargetMIPS32::lowerRet(const InstRet *Inst) { void TargetMIPS32::lowerRet(const InstRet *Inst) {
(void)Inst; Variable *Reg = nullptr;
llvm::report_fatal_error("Not yet implemented"); if (Inst->hasRetValue())
UnimplementedError(Func->getContext()->getFlags());
_ret(getPhysicalRegister(RegMIPS32::Reg_RA), Reg);
} }
void TargetMIPS32::lowerSelect(const InstSelect *Inst) { void TargetMIPS32::lowerSelect(const InstSelect *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerStore(const InstStore *Inst) { void TargetMIPS32::lowerStore(const InstStore *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::doAddressOptStore() { void TargetMIPS32::doAddressOptStore() {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerSwitch(const InstSwitch *Inst) { void TargetMIPS32::lowerSwitch(const InstSwitch *Inst) {
(void)Inst; (void)Inst;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::lowerUnreachable(const InstUnreachable * /*Inst*/) { void TargetMIPS32::lowerUnreachable(const InstUnreachable * /*Inst*/) {
llvm_unreachable("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to
...@@ -630,7 +646,7 @@ void TargetMIPS32::lowerUnreachable(const InstUnreachable * /*Inst*/) { ...@@ -630,7 +646,7 @@ void TargetMIPS32::lowerUnreachable(const InstUnreachable * /*Inst*/) {
// turned into zeroes, since loOperand() and hiOperand() don't expect // turned into zeroes, since loOperand() and hiOperand() don't expect
// Undef input. // Undef input.
void TargetMIPS32::prelowerPhis() { void TargetMIPS32::prelowerPhis() {
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
// Lower the pre-ordered list of assignments into mov instructions. // Lower the pre-ordered list of assignments into mov instructions.
...@@ -639,7 +655,7 @@ void TargetMIPS32::lowerPhiAssignments(CfgNode *Node, ...@@ -639,7 +655,7 @@ void TargetMIPS32::lowerPhiAssignments(CfgNode *Node,
const AssignList &Assignments) { const AssignList &Assignments) {
(void)Node; (void)Node;
(void)Assignments; (void)Assignments;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::postLower() { void TargetMIPS32::postLower() {
...@@ -647,7 +663,7 @@ void TargetMIPS32::postLower() { ...@@ -647,7 +663,7 @@ void TargetMIPS32::postLower() {
return; return;
// Find two-address non-SSA instructions where Dest==Src0, and set // Find two-address non-SSA instructions where Dest==Src0, and set
// the DestNonKillable flag to keep liveness analysis consistent. // the DestNonKillable flag to keep liveness analysis consistent.
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
void TargetMIPS32::makeRandomRegisterPermutation( void TargetMIPS32::makeRandomRegisterPermutation(
...@@ -655,7 +671,7 @@ void TargetMIPS32::makeRandomRegisterPermutation( ...@@ -655,7 +671,7 @@ void TargetMIPS32::makeRandomRegisterPermutation(
const llvm::SmallBitVector &ExcludeRegisters) const { const llvm::SmallBitVector &ExcludeRegisters) const {
(void)Permutation; (void)Permutation;
(void)ExcludeRegisters; (void)ExcludeRegisters;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Func->getContext()->getFlags());
} }
/* TODO(jvoung): avoid duplicate symbols with multiple targets. /* TODO(jvoung): avoid duplicate symbols with multiple targets.
...@@ -694,7 +710,7 @@ void TargetDataMIPS32::lowerGlobals(const VariableDeclarationList &Vars, ...@@ -694,7 +710,7 @@ void TargetDataMIPS32::lowerGlobals(const VariableDeclarationList &Vars,
void TargetDataMIPS32::lowerConstants() { void TargetDataMIPS32::lowerConstants() {
if (Ctx->getFlags().getDisableTranslation()) if (Ctx->getFlags().getDisableTranslation())
return; return;
llvm::report_fatal_error("Not yet implemented"); UnimplementedError(Ctx->getFlags());
} }
TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx) TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx)
......
...@@ -76,6 +76,9 @@ public: ...@@ -76,6 +76,9 @@ public:
(void)C; (void)C;
llvm::report_fatal_error("Not yet implemented"); llvm::report_fatal_error("Not yet implemented");
} }
void _ret(Variable *RA, Variable *Src0 = nullptr) {
Context.insert(InstMIPS32Ret::create(Func, RA, Src0));
}
void lowerArguments() override; void lowerArguments() override;
void addProlog(CfgNode *Node) override; void addProlog(CfgNode *Node) override;
......
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \ ; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s ; RUN: --command FileCheck --check-prefix ARM32 %s
; RUN: %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target mips32 -i %s --args -O2 --skip-unimplemented \
; RUN: | %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix MIPS32 %s
define void @foo() { define void @foo() {
ret void ret void
...@@ -25,6 +30,10 @@ define void @foo() { ...@@ -25,6 +30,10 @@ define void @foo() {
; ARM32-NEXT: 4: e7fedef0 udf ; ARM32-NEXT: 4: e7fedef0 udf
; ARM32-NEXT: 8: e7fedef0 udf ; ARM32-NEXT: 8: e7fedef0 udf
; ARM32-NEXT: c: e7fedef0 udf ; ARM32-NEXT: c: e7fedef0 udf
; MIPS32-LABEL: foo
; MIPS32: 4: {{.*}} jr ra
; MIPS32-NEXT: 8: {{.*}} nop
; MIPS32-NEXT: c: e7fedef0
define void @bar() { define void @bar() {
ret void ret void
...@@ -33,3 +42,6 @@ define void @bar() { ...@@ -33,3 +42,6 @@ define void @bar() {
; CHECK-NEXT: 20: {{.*}} ret ; CHECK-NEXT: 20: {{.*}} ret
; ARM32-LABEL: bar ; ARM32-LABEL: bar
; ARM32-NEXT: 10: {{.*}} bx lr ; ARM32-NEXT: 10: {{.*}} bx lr
; MIPS32-LABEL: bar
; MIPS32: 14: {{.*}} jr ra
; MIPS32-NEXT: 18: {{.*}} nop
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment