From 205b71dae094e97cddf48c6e9dfbe1087e2a3a81 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Fri, 10 Apr 2026 00:00:03 -0400 Subject: [PATCH] goalc/arm: another couple dozen instructions --- goalc/emitter/IGen.cpp | 42 ++++---- goalc/emitter/IGenARM64.cpp | 201 +++++++++++++++++++++++++----------- goalc/emitter/IGenARM64.h | 42 ++++---- goalc/emitter/Instruction.h | 15 +++ 4 files changed, 195 insertions(+), 105 deletions(-) diff --git a/goalc/emitter/IGen.cpp b/goalc/emitter/IGen.cpp index 49bbf27e13..f59b12ca84 100644 --- a/goalc/emitter/IGen.cpp +++ b/goalc/emitter/IGen.cpp @@ -718,87 +718,87 @@ Instruction sar_gpr64_u8(const ObjectGenerator& gen, Register reg, uint8_t sa) { } Instruction jmp_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(jmp_32); + IGEN_DISPATCH(jmp_imm); } Instruction je_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(je_32); + IGEN_DISPATCH(je_imm); } Instruction jne_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(jne_32); + IGEN_DISPATCH(jne_imm); } Instruction jle_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(jle_32); + IGEN_DISPATCH(jle_imm); } Instruction jge_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(jge_32); + IGEN_DISPATCH(jge_imm); } Instruction jl_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(jl_32); + IGEN_DISPATCH(jl_imm); } Instruction jg_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(jg_32); + IGEN_DISPATCH(jg_imm); } Instruction jbe_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(jbe_32); + IGEN_DISPATCH(jbe_imm); } Instruction jae_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(jae_32); + IGEN_DISPATCH(jae_imm); } Instruction jb_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(jb_32); + IGEN_DISPATCH(jb_imm); } Instruction ja_32(const ObjectGenerator& gen) { - IGEN_DISPATCH(ja_32); + IGEN_DISPATCH(ja_imm); } Instruction cmp_flt_flt(const ObjectGenerator& gen, Register a, Register b) { - IGEN_DISPATCH(cmp_flt_flt, a, b); + IGEN_DISPATCH(cmp_f32_f32, a, b); } Instruction sqrts_xmm(const ObjectGenerator& gen, Register dst, Register src) { - IGEN_DISPATCH(sqrts_xmm, dst, src); + IGEN_DISPATCH(sqrt_f32, dst, src); } Instruction mulss_xmm_xmm(const ObjectGenerator& gen, Register dst, Register src) { - IGEN_DISPATCH(mulss_xmm_xmm, dst, src); + IGEN_DISPATCH(mul_f32_f32, dst, src); } Instruction divss_xmm_xmm(const ObjectGenerator& gen, Register dst, Register src) { - IGEN_DISPATCH(divss_xmm_xmm, dst, src); + IGEN_DISPATCH(div_f32_f32, dst, src); } Instruction subss_xmm_xmm(const ObjectGenerator& gen, Register dst, Register src) { - IGEN_DISPATCH(subss_xmm_xmm, dst, src); + IGEN_DISPATCH(sub_f32_f32, dst, src); } Instruction addss_xmm_xmm(const ObjectGenerator& gen, Register dst, Register src) { - IGEN_DISPATCH(addss_xmm_xmm, dst, src); + IGEN_DISPATCH(add_f32_f32, dst, src); } Instruction minss_xmm_xmm(const ObjectGenerator& gen, Register dst, Register src) { - IGEN_DISPATCH(minss_xmm_xmm, dst, src); + IGEN_DISPATCH(min_f32_f32, dst, src); } Instruction maxss_xmm_xmm(const ObjectGenerator& gen, Register dst, Register src) { - IGEN_DISPATCH(maxss_xmm_xmm, dst, src); + IGEN_DISPATCH(max_f32_f32, dst, src); } Instruction int32_to_float(const ObjectGenerator& gen, Register dst, Register src) { - IGEN_DISPATCH(int32_to_float, dst, src); + IGEN_DISPATCH(int32_to_f32, dst, src); } Instruction float_to_int32(const ObjectGenerator& gen, Register dst, Register src) { - IGEN_DISPATCH(float_to_int32, dst, src); + IGEN_DISPATCH(f32_to_int32, dst, src); } Instruction nop(const ObjectGenerator& gen) { diff --git a/goalc/emitter/IGenARM64.cpp b/goalc/emitter/IGenARM64.cpp index 16d5436477..6a245f4d00 100644 --- a/goalc/emitter/IGenARM64.cpp +++ b/goalc/emitter/IGenARM64.cpp @@ -849,114 +849,189 @@ InstructionARM64 sar_gpr64_u8(Register reg, uint8_t sa) { //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; // CONTROL FLOW //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +// +// All of these instructions jump to a target that is zero +// and then its up to the IR to patch the actual target +// +// Critically, on arm these relative targets must be within +// 128MB, which is much less than x86 (~2GB) +// +// However, these functions are only really used for jumps within +// a given function...of which the largest we've seen isn't even in the MB +// of sizes +// +// So for now, keep it simple and don't implement something more +// complicated like veneers, this should be fine. -InstructionARM64 jmp_32() { - ASSERT_MSG(false, "not yet implemented"); - return InstructionARM64(0b0); +InstructionARM64 jmp_imm() { + // https://www.scs.stanford.edu/~zyedidia/arm64/b_uncond.html + // B