Commit 3b61d70e by Srdjan Obucina Committed by Jim Stichnoth

Subzero, MIPS32: lowerUnreachable

Patch implements lowerUnreachable and encoding for teq instruction. To avoid duplicated code, class describing trap instruction is borrowed from https://codereview.chromium.org/2339323004/ Review URL: https://codereview.chromium.org/2350903002 . Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
parent cc6dea76
......@@ -653,6 +653,17 @@ void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase,
}
}
void AssemblerMIPS32::teq(const Operand *OpRs, const Operand *OpRt,
const uint32_t TrapCode) {
IValueT Opcode = 0x00000034;
const IValueT Rs = encodeGPRegister(OpRs, "Rs", "teq");
const IValueT Rt = encodeGPRegister(OpRt, "Rt", "teq");
Opcode |= (TrapCode & 0xFFFFF) << 6;
Opcode |= Rt << 16;
Opcode |= Rs << 21;
emitInst(Opcode);
}
void AssemblerMIPS32::trunc_l_d(const Operand *OpFd, const Operand *OpFs) {
static constexpr IValueT Opcode = 0x4400000D;
emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "trunc.l.d");
......
......@@ -178,6 +178,8 @@ public:
void sw(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset);
void teq(const Operand *OpRs, const Operand *OpRt, const uint32_t TrapCode);
void trunc_l_d(const Operand *OpFd, const Operand *OpFs);
void trunc_l_s(const Operand *OpFd, const Operand *OpFs);
......
......@@ -990,6 +990,11 @@ template <> void InstMIPS32Sw::emitIAS(const Cfg *Func) const {
Asm->sw(getSrc(0), Mem->getBase(), Imm);
}
template <> void InstMIPS32Teq::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Asm->teq(getSrc(0), getSrc(1), getTrapCode());
}
template <> void InstMIPS32Trunc_l_d::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Asm->trunc_l_d(getDest(), getSrc(0));
......
......@@ -928,6 +928,8 @@ public:
InstMIPS32Trap(Func, Src0, Src1, Tcode);
}
uint32_t getTrapCode() const { return TrapCode; }
void emit(const Cfg *Func) const override {
if (!BuildDefs::dump())
return;
......@@ -1275,6 +1277,7 @@ template <> void InstMIPS32Sra::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Srl::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Sub_d::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Sub_s::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Teq::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Trunc_l_d::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Trunc_l_s::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Trunc_w_d::emitIAS(const Cfg *Func) const;
......
......@@ -3299,8 +3299,9 @@ void TargetMIPS32::lowerBreakpoint(const InstBreakpoint *Instr) {
UnimplementedLoweringError(this, Instr);
}
void TargetMIPS32::lowerUnreachable(const InstUnreachable *Instr) {
UnimplementedLoweringError(this, Instr);
void TargetMIPS32::lowerUnreachable(const InstUnreachable *) {
const uint32_t TrapCodeZero = 0;
_teq(getZero(), getZero(), TrapCodeZero);
}
// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve
......
; Test encoding of MIPS32 floating point arithmetic instructions
; REQUIRES: allow_dump
; Compile using standalone assembler.
; RUN: %p2i --filetype=asm -i %s --target=mips32 --args -O2 \
; RUN: --allow-externally-defined-symbols --skip-unimplemented \
; RUN: | FileCheck %s --check-prefix=ASM
; Show bytes in assembled standalone code.
; RUN: %p2i --filetype=asm -i %s --target=mips32 --assemble --disassemble \
; RUN: --args -O2 --allow-externally-defined-symbols --skip-unimplemented \
; RUN: | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=mips32 --args -O2 \
; RUN: --allow-externally-defined-symbols --skip-unimplemented \
; RUN: | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=mips32 --assemble --disassemble \
; RUN: --args -O2 --allow-externally-defined-symbols --skip-unimplemented \
; RUN: | FileCheck %s --check-prefix=DIS
define internal void @encTrap() {
unreachable
}
; ASM-LABEL: encTrap
; ASM-NEXT: .LencTrap$__0:
; ASM-NEXT: teq $zero, $zero, 0
; DIS-LABEL: 00000000 <encTrap>:
; DIS-NEXT: 0: 00000034 teq zero,zero
; IASM-LABEL: encTrap:
; IASM-NEXT: .LencTrap$__0:
; IASM-NEXT: .byte 0x34
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
......@@ -18,6 +18,18 @@
; RUN: | %if --need=target_ARM32 --need=allow_dump \
; 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 -Om1 --skip-unimplemented \
; RUN: | %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix MIPS32 %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-O2 %s
define internal i32 @divide(i32 %num, i32 %den) {
entry:
%cmp = icmp ne i32 %den, 0
......@@ -43,3 +55,15 @@ return: ; preds = %entry
; ARM32: .word 0xe7fedef0
; ARM32: bl {{.*}} __divsi3
; ARM32: bx lr
; MIPS32-LABEL: divide
; MIPS32: beqz
; MIPS32: nop
; MIPS32: teq zero,zero
; MIPS32: div
; MIPS32-O2-LABEL: divide
; MIPS32-O2: bne
; MIPS32-O2: nop
; MIPS32-O2: teq zero,zero
; MIPS32-O2: div
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