From 2a68a1b35b1e4f799a3a753ed9018e2d469b77b5 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 8 Jul 2014 16:01:40 -0700 Subject: [PATCH] Special casing some VC++ traps. --- src/alloy/backend/ivm/ivm_intcode.cc | 9 ++++++++- src/alloy/backend/x64/x64_emitter.cc | 21 +++++++++++++++++---- src/alloy/backend/x64/x64_emitter.h | 2 +- src/alloy/backend/x64/x64_sequences.cc | 14 +++++++------- src/alloy/frontend/ppc/ppc_emit_control.cc | 8 +++++++- src/alloy/hir/hir_builder.cc | 10 +++++----- src/alloy/hir/hir_builder.h | 4 ++-- 7 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 1badeab7e..109bb19a9 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -309,8 +309,15 @@ int Translate_DEBUG_BREAK_TRUE(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_TRAP(IntCodeState& ics, const IntCode* i) { - // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length // TODO(benvanik): post software interrupt to debugger. + switch (i->flags) { + case 20: + // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length + break; + case 22: + // Always trap? + break; + } __debugbreak(); return IA_NEXT; } diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 0e2d55860..ab0d2123b 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -219,10 +219,23 @@ void X64Emitter::DebugBreak() { db(0xCC); } -void X64Emitter::Trap() { - // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length - // TODO(benvanik): post software interrupt to debugger. - db(0xCC); +void X64Emitter::Trap(uint16_t trap_type) { + switch (trap_type) { + case 20: + // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length + // TODO(benvanik): debug print at runtime. + break; + case 0: + case 22: + // Always trap? + // TODO(benvanik): post software interrupt to debugger. + db(0xCC); + break; + default: + XELOGW("Unknown trap type %d", trap_type); + db(0xCC); + break; + } } void X64Emitter::UnimplementedInstr(const hir::Instr* i) { diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index e6ea7b7b5..3bfe43a2b 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -117,7 +117,7 @@ public: void MarkSourceOffset(const hir::Instr* i); void DebugBreak(); - void Trap(); + void Trap(uint16_t trap_type = 0); void UnimplementedInstr(const hir::Instr* i); void UnimplementedExtern(const hir::Instr* i); diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 689c8b3b3..e06f69a99 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -191,7 +191,7 @@ EMITTER_OPCODE_TABLE( // ============================================================================ EMITTER(TRAP, MATCH(I)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - e.Trap(); + e.Trap(i.instr->flags); } }; EMITTER_OPCODE_TABLE( @@ -207,7 +207,7 @@ EMITTER(TRAP_TRUE_I8, MATCH(I>)) { e.test(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -216,7 +216,7 @@ EMITTER(TRAP_TRUE_I16, MATCH(I>)) { e.test(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -225,7 +225,7 @@ EMITTER(TRAP_TRUE_I32, MATCH(I>)) { e.test(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -234,7 +234,7 @@ EMITTER(TRAP_TRUE_I64, MATCH(I>)) { e.test(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -243,7 +243,7 @@ EMITTER(TRAP_TRUE_F32, MATCH(I>)) { e.vptest(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -252,7 +252,7 @@ EMITTER(TRAP_TRUE_F64, MATCH(I>)) { e.vptest(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 0365c849b..111be91a3 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -400,7 +400,7 @@ XEEMITTER(sc, 0x44000002, SC )(PPCHIRBuilder& f, InstrData& i) { // Trap (A-25) int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, - Value* va, Value* vb, uint32_t TO) { + Value* va, Value* vb, uint32_t TO) { // if (a < b) & TO[0] then TRAP // if (a > b) & TO[1] then TRAP // if (a = b) & TO[2] then TRAP @@ -482,6 +482,12 @@ XEEMITTER(twi, 0x0C000000, D )(PPCHIRBuilder& f, InstrData& i) { // if (a = EXTS(SI)) & TO[2] then TRAP // if (a u EXTS(SI)) & TO[4] then TRAP + if (i.D.RA == 0 && i.D.RT == 0x1F) { + // This is a special trap. Probably. + uint16_t type = (uint16_t)XEEXTS16(i.D.DS); + f.Trap(type); + return 0; + } Value* ra = f.SignExtend(f.Truncate( f.LoadGPR(i.D.RA), INT32_TYPE), INT64_TYPE); Value* rb = f.LoadConstant(XEEXTS16(i.D.DS)); diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 158e08224..de0ce4a34 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -577,21 +577,21 @@ void HIRBuilder::DebugBreakTrue(Value* cond) { EndBlock(); } -void HIRBuilder::Trap() { - Instr* i = AppendInstr(OPCODE_TRAP_info, 0); +void HIRBuilder::Trap(uint16_t trap_code) { + Instr* i = AppendInstr(OPCODE_TRAP_info, trap_code); i->src1.value = i->src2.value = i->src3.value = NULL; EndBlock(); } -void HIRBuilder::TrapTrue(Value* cond) { +void HIRBuilder::TrapTrue(Value* cond, uint16_t trap_code) { if (cond->IsConstant()) { if (cond->IsConstantTrue()) { - Trap(); + Trap(trap_code); } return; } - Instr* i = AppendInstr(OPCODE_TRAP_TRUE_info, 0); + Instr* i = AppendInstr(OPCODE_TRAP_TRUE_info, trap_code); i->set_src1(cond); i->src2.value = i->src3.value = NULL; EndBlock(); diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index 6568a5a49..7703dc8f1 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -71,8 +71,8 @@ public: void DebugBreak(); void DebugBreakTrue(Value* cond); - void Trap(); - void TrapTrue(Value* cond); + void Trap(uint16_t trap_code = 0); + void TrapTrue(Value* cond, uint16_t trap_code = 0); void Call(runtime::FunctionInfo* symbol_info, uint32_t call_flags = 0); void CallTrue(Value* cond, runtime::FunctionInfo* symbol_info,