compiler: delete aarch64 backend

this backend was abandoned before it was completed, and it is not worth
salvaging.
This commit is contained in:
Andrew Kelley 2025-07-02 14:40:25 -07:00
parent 80a9b8f326
commit 20a543097b
7 changed files with 6 additions and 8356 deletions

View file

@ -549,11 +549,6 @@ set(ZIG_STAGE2_SOURCES
src/Value.zig src/Value.zig
src/Zcu.zig src/Zcu.zig
src/Zcu/PerThread.zig src/Zcu/PerThread.zig
src/arch/aarch64/CodeGen.zig
src/arch/aarch64/Emit.zig
src/arch/aarch64/Mir.zig
src/arch/aarch64/abi.zig
src/arch/aarch64/bits.zig
src/arch/arm/CodeGen.zig src/arch/arm/CodeGen.zig
src/arch/arm/Emit.zig src/arch/arm/Emit.zig
src/arch/arm/Mir.zig src/arch/arm/Mir.zig

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,568 +0,0 @@
//! Machine Intermediate Representation.
//! This data is produced by AArch64 Codegen or AArch64 assembly parsing
//! These instructions have a 1:1 correspondence with machine code instructions
//! for the target. MIR can be lowered to source-annotated textual assembly code
//! instructions, or it can be lowered to machine code.
//! The main purpose of MIR is to postpone the assignment of offsets until Isel,
//! so that, for example, the smaller encodings of jump instructions can be used.
const Mir = @This();
const std = @import("std");
const builtin = @import("builtin");
const assert = std.debug.assert;
const bits = @import("bits.zig");
const Register = bits.Register;
const InternPool = @import("../../InternPool.zig");
const Emit = @import("Emit.zig");
const codegen = @import("../../codegen.zig");
const link = @import("../../link.zig");
const Zcu = @import("../../Zcu.zig");
max_end_stack: u32,
saved_regs_stack_space: u32,
instructions: std.MultiArrayList(Inst).Slice,
/// The meaning of this data is determined by `Inst.Tag` value.
extra: []const u32,
pub const Inst = struct {
tag: Tag,
/// The meaning of this depends on `tag`.
data: Data,
pub const Tag = enum(u16) {
/// Add (immediate)
add_immediate,
/// Add, update condition flags (immediate)
adds_immediate,
/// Add (shifted register)
add_shifted_register,
/// Add, update condition flags (shifted register)
adds_shifted_register,
/// Add (extended register)
add_extended_register,
/// Add, update condition flags (extended register)
adds_extended_register,
/// Bitwise AND (shifted register)
and_shifted_register,
/// Arithmetic Shift Right (immediate)
asr_immediate,
/// Arithmetic Shift Right (register)
asr_register,
/// Branch conditionally
b_cond,
/// Branch
b,
/// Branch with Link
bl,
/// Branch with Link to Register
blr,
/// Breakpoint
brk,
/// Pseudo-instruction: Call extern
call_extern,
/// Compare and Branch on Zero
cbz,
/// Compare (immediate)
cmp_immediate,
/// Compare (shifted register)
cmp_shifted_register,
/// Compare (extended register)
cmp_extended_register,
/// Conditional Select
csel,
/// Conditional set
cset,
/// Pseudo-instruction: End of prologue
dbg_prologue_end,
/// Pseudo-instruction: Beginning of epilogue
dbg_epilogue_begin,
/// Pseudo-instruction: Update debug line
dbg_line,
/// Bitwise Exclusive OR (immediate)
eor_immediate,
/// Bitwise Exclusive OR (shifted register)
eor_shifted_register,
/// Loads the contents into a register
///
/// Payload is `LoadMemoryPie`
load_memory_got,
/// Loads the contents into a register
///
/// Payload is `LoadMemoryPie`
load_memory_direct,
/// Loads the contents into a register
///
/// Payload is `LoadMemoryPie`
load_memory_import,
/// Loads the address into a register
///
/// Payload is `LoadMemoryPie`
load_memory_ptr_got,
/// Loads the address into a register
///
/// Payload is `LoadMemoryPie`
load_memory_ptr_direct,
/// Load Pair of Registers
ldp,
/// Pseudo-instruction: Load pointer to stack item
ldr_ptr_stack,
/// Pseudo-instruction: Load pointer to stack argument
ldr_ptr_stack_argument,
/// Pseudo-instruction: Load from stack
ldr_stack,
/// Pseudo-instruction: Load from stack argument
ldr_stack_argument,
/// Load Register (immediate)
ldr_immediate,
/// Load Register (register)
ldr_register,
/// Pseudo-instruction: Load byte from stack
ldrb_stack,
/// Pseudo-instruction: Load byte from stack argument
ldrb_stack_argument,
/// Load Register Byte (immediate)
ldrb_immediate,
/// Load Register Byte (register)
ldrb_register,
/// Pseudo-instruction: Load halfword from stack
ldrh_stack,
/// Pseudo-instruction: Load halfword from stack argument
ldrh_stack_argument,
/// Load Register Halfword (immediate)
ldrh_immediate,
/// Load Register Halfword (register)
ldrh_register,
/// Load Register Signed Byte (immediate)
ldrsb_immediate,
/// Pseudo-instruction: Load signed byte from stack
ldrsb_stack,
/// Pseudo-instruction: Load signed byte from stack argument
ldrsb_stack_argument,
/// Load Register Signed Halfword (immediate)
ldrsh_immediate,
/// Pseudo-instruction: Load signed halfword from stack
ldrsh_stack,
/// Pseudo-instruction: Load signed halfword from stack argument
ldrsh_stack_argument,
/// Load Register Signed Word (immediate)
ldrsw_immediate,
/// Logical Shift Left (immediate)
lsl_immediate,
/// Logical Shift Left (register)
lsl_register,
/// Logical Shift Right (immediate)
lsr_immediate,
/// Logical Shift Right (register)
lsr_register,
/// Move (to/from SP)
mov_to_from_sp,
/// Move (register)
mov_register,
/// Move wide with keep
movk,
/// Move wide with zero
movz,
/// Multiply-subtract
msub,
/// Multiply
mul,
/// Bitwise NOT
mvn,
/// No Operation
nop,
/// Bitwise inclusive OR (shifted register)
orr_shifted_register,
/// Pseudo-instruction: Pop multiple registers
pop_regs,
/// Pseudo-instruction: Push multiple registers
push_regs,
/// Return from subroutine
ret,
/// Signed bitfield extract
sbfx,
/// Signed divide
sdiv,
/// Signed multiply high
smulh,
/// Signed multiply long
smull,
/// Signed extend byte
sxtb,
/// Signed extend halfword
sxth,
/// Signed extend word
sxtw,
/// Store Pair of Registers
stp,
/// Pseudo-instruction: Store to stack
str_stack,
/// Store Register (immediate)
str_immediate,
/// Store Register (register)
str_register,
/// Pseudo-instruction: Store byte to stack
strb_stack,
/// Store Register Byte (immediate)
strb_immediate,
/// Store Register Byte (register)
strb_register,
/// Pseudo-instruction: Store halfword to stack
strh_stack,
/// Store Register Halfword (immediate)
strh_immediate,
/// Store Register Halfword (register)
strh_register,
/// Subtract (immediate)
sub_immediate,
/// Subtract, update condition flags (immediate)
subs_immediate,
/// Subtract (shifted register)
sub_shifted_register,
/// Subtract, update condition flags (shifted register)
subs_shifted_register,
/// Subtract (extended register)
sub_extended_register,
/// Subtract, update condition flags (extended register)
subs_extended_register,
/// Supervisor Call
svc,
/// Test bits (immediate)
tst_immediate,
/// Unsigned bitfield extract
ubfx,
/// Unsigned divide
udiv,
/// Unsigned multiply high
umulh,
/// Unsigned multiply long
umull,
/// Unsigned extend byte
uxtb,
/// Unsigned extend halfword
uxth,
};
/// The position of an MIR instruction within the `Mir` instructions array.
pub const Index = u32;
/// All instructions have a 4-byte payload, which is contained within
/// this union. `Tag` determines which union field is active, as well as
/// how to interpret the data within.
pub const Data = union {
/// No additional data
///
/// Used by e.g. nop
nop: void,
/// Another instruction
///
/// Used by e.g. b
inst: Index,
/// Relocation for the linker where:
/// * `atom_index` is the index of the source
/// * `sym_index` is the index of the target
///
/// Used by e.g. call_extern
relocation: struct {
/// Index of the containing atom.
atom_index: u32,
/// Index into the linker's string table.
sym_index: u32,
},
/// A 16-bit immediate value.
///
/// Used by e.g. svc
imm16: u16,
/// Index into `extra`. Meaning of what can be found there is context-dependent.
payload: u32,
/// A register
///
/// Used by e.g. blr
reg: Register,
/// Multiple registers
///
/// Used by e.g. pop_regs
reg_list: u32,
/// Another instruction and a condition
///
/// Used by e.g. b_cond
inst_cond: struct {
inst: Index,
cond: bits.Instruction.Condition,
},
/// A register, an unsigned 16-bit immediate, and an optional shift
///
/// Used by e.g. movz
r_imm16_sh: struct {
rd: Register,
imm16: u16,
hw: u2 = 0,
},
/// A register and a condition
///
/// Used by e.g. cset
r_cond: struct {
rd: Register,
cond: bits.Instruction.Condition,
},
/// A register and another instruction
///
/// Used by e.g. cbz
r_inst: struct {
rt: Register,
inst: Index,
},
/// A register, an unsigned 12-bit immediate, and an optional shift
///
/// Used by e.g. cmp_immediate
r_imm12_sh: struct {
rn: Register,
imm12: u12,
sh: u1 = 0,
},
/// Two registers
///
/// Used by e.g. mov_register
rr: struct {
rd: Register,
rn: Register,
},
/// Two registers, an unsigned 12-bit immediate, and an optional shift
///
/// Used by e.g. sub_immediate
rr_imm12_sh: struct {
rd: Register,
rn: Register,
imm12: u12,
sh: u1 = 0,
},
/// Two registers and a shift (shift type and 6-bit amount)
///
/// Used by e.g. cmp_shifted_register
rr_imm6_shift: struct {
rn: Register,
rm: Register,
imm6: u6,
shift: bits.Instruction.AddSubtractShiftedRegisterShift,
},
/// Two registers with sign-extension (extension type and 3-bit shift amount)
///
/// Used by e.g. cmp_extended_register
rr_extend_shift: struct {
rn: Register,
rm: Register,
ext_type: bits.Instruction.AddSubtractExtendedRegisterOption,
imm3: u3,
},
/// Two registers and a shift (logical instruction version)
/// (shift type and 6-bit amount)
///
/// Used by e.g. mvn
rr_imm6_logical_shift: struct {
rd: Register,
rm: Register,
imm6: u6,
shift: bits.Instruction.LogicalShiftedRegisterShift,
},
/// Two registers and a lsb (range 0-63) and a width (range
/// 1-64)
///
/// Used by e.g. ubfx
rr_lsb_width: struct {
rd: Register,
rn: Register,
lsb: u6,
width: u7,
},
/// Two registers and a bitmask immediate
///
/// Used by e.g. eor_immediate
rr_bitmask: struct {
rd: Register,
rn: Register,
imms: u6,
immr: u6,
n: u1,
},
/// Two registers and a 6-bit unsigned shift
///
/// Used by e.g. lsl_immediate
rr_shift: struct {
rd: Register,
rn: Register,
shift: u6,
},
/// Three registers
///
/// Used by e.g. mul
rrr: struct {
rd: Register,
rn: Register,
rm: Register,
},
/// Three registers and a condition
///
/// Used by e.g. csel
rrr_cond: struct {
rd: Register,
rn: Register,
rm: Register,
cond: bits.Instruction.Condition,
},
/// Three registers and a shift (shift type and 6-bit amount)
///
/// Used by e.g. add_shifted_register
rrr_imm6_shift: struct {
rd: Register,
rn: Register,
rm: Register,
imm6: u6,
shift: bits.Instruction.AddSubtractShiftedRegisterShift,
},
/// Three registers with sign-extension (extension type and 3-bit shift amount)
///
/// Used by e.g. add_extended_register
rrr_extend_shift: struct {
rd: Register,
rn: Register,
rm: Register,
ext_type: bits.Instruction.AddSubtractExtendedRegisterOption,
imm3: u3,
},
/// Three registers and a shift (logical instruction version)
/// (shift type and 6-bit amount)
///
/// Used by e.g. eor_shifted_register
rrr_imm6_logical_shift: struct {
rd: Register,
rn: Register,
rm: Register,
imm6: u6,
shift: bits.Instruction.LogicalShiftedRegisterShift,
},
/// Two registers and a LoadStoreOffsetImmediate
///
/// Used by e.g. str_immediate
load_store_register_immediate: struct {
rt: Register,
rn: Register,
offset: bits.Instruction.LoadStoreOffsetImmediate,
},
/// Two registers and a LoadStoreOffsetRegister
///
/// Used by e.g. str_register
load_store_register_register: struct {
rt: Register,
rn: Register,
offset: bits.Instruction.LoadStoreOffsetRegister,
},
/// A register and a stack offset
///
/// Used by e.g. str_stack
load_store_stack: struct {
rt: Register,
offset: u32,
},
/// Three registers and a LoadStorePairOffset
///
/// Used by e.g. stp
load_store_register_pair: struct {
rt: Register,
rt2: Register,
rn: Register,
offset: bits.Instruction.LoadStorePairOffset,
},
/// Four registers
///
/// Used by e.g. msub
rrrr: struct {
rd: Register,
rn: Register,
rm: Register,
ra: Register,
},
/// Debug info: line and column
///
/// Used by e.g. dbg_line
dbg_line_column: struct {
line: u32,
column: u32,
},
};
// Make sure we don't accidentally make instructions bigger than expected.
// Note that in safety builds, Zig is allowed to insert a secret field for safety checks.
comptime {
if (!std.debug.runtime_safety) {
assert(@sizeOf(Data) == 8);
}
}
};
pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
mir.instructions.deinit(gpa);
gpa.free(mir.extra);
mir.* = undefined;
}
pub fn emit(
mir: Mir,
lf: *link.File,
pt: Zcu.PerThread,
src_loc: Zcu.LazySrcLoc,
func_index: InternPool.Index,
code: *std.ArrayListUnmanaged(u8),
debug_output: link.File.DebugInfoOutput,
) codegen.CodeGenError!void {
const zcu = pt.zcu;
const func = zcu.funcInfo(func_index);
const nav = func.owner_nav;
const mod = zcu.navFileScope(nav).mod.?;
var e: Emit = .{
.mir = mir,
.bin_file = lf,
.debug_output = debug_output,
.target = &mod.resolved_target.result,
.src_loc = src_loc,
.code = code,
.prev_di_pc = 0,
.prev_di_line = func.lbrace_line,
.prev_di_column = func.lbrace_column,
.stack_size = mir.max_end_stack,
.saved_regs_stack_space = mir.saved_regs_stack_space,
};
defer e.deinit();
e.emitMir() catch |err| switch (err) {
error.EmitFail => return zcu.codegenFailMsg(nav, e.err_msg.?),
else => |e1| return e1,
};
}
/// Returns the requested data, as well as the new index which is at the start of the
/// trailers for the object.
pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
const fields = std.meta.fields(T);
var i: usize = index;
var result: T = undefined;
inline for (fields) |field| {
@field(result, field.name) = switch (field.type) {
u32 => mir.extra[i],
i32 => @as(i32, @bitCast(mir.extra[i])),
else => @compileError("bad field type"),
};
i += 1;
}
return .{
.data = result,
.end = i,
};
}
pub const LoadMemoryPie = struct {
register: u32,
/// Index of the containing atom.
atom_index: u32,
/// Index into the linker's symbol table.
sym_index: u32,
};

View file

@ -48,7 +48,7 @@ fn devFeatureForBackend(backend: std.builtin.CompilerBackend) dev.Feature {
fn importBackend(comptime backend: std.builtin.CompilerBackend) type { fn importBackend(comptime backend: std.builtin.CompilerBackend) type {
return switch (backend) { return switch (backend) {
.other, .stage1 => unreachable, .other, .stage1 => unreachable,
.stage2_aarch64 => @import("arch/aarch64/CodeGen.zig"), .stage2_aarch64 => unreachable,
.stage2_arm => @import("arch/arm/CodeGen.zig"), .stage2_arm => @import("arch/arm/CodeGen.zig"),
.stage2_c => @import("codegen/c.zig"), .stage2_c => @import("codegen/c.zig"),
.stage2_llvm => @import("codegen/llvm.zig"), .stage2_llvm => @import("codegen/llvm.zig"),
@ -72,7 +72,6 @@ pub fn legalizeFeatures(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) ?*co
.stage2_wasm, .stage2_wasm,
.stage2_arm, .stage2_arm,
.stage2_x86_64, .stage2_x86_64,
.stage2_aarch64,
.stage2_x86, .stage2_x86,
.stage2_riscv64, .stage2_riscv64,
.stage2_sparc64, .stage2_sparc64,
@ -88,7 +87,6 @@ pub fn legalizeFeatures(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) ?*co
/// MIR from codegen to the linker *regardless* of which backend is in use. So, we use this: a /// MIR from codegen to the linker *regardless* of which backend is in use. So, we use this: a
/// union of all MIR types. The active tag is known from the backend in use; see `AnyMir.tag`. /// union of all MIR types. The active tag is known from the backend in use; see `AnyMir.tag`.
pub const AnyMir = union { pub const AnyMir = union {
aarch64: @import("arch/aarch64/Mir.zig"),
arm: @import("arch/arm/Mir.zig"), arm: @import("arch/arm/Mir.zig"),
riscv64: @import("arch/riscv64/Mir.zig"), riscv64: @import("arch/riscv64/Mir.zig"),
sparc64: @import("arch/sparc64/Mir.zig"), sparc64: @import("arch/sparc64/Mir.zig"),
@ -114,8 +112,7 @@ pub const AnyMir = union {
const backend = target_util.zigBackend(&zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm); const backend = target_util.zigBackend(&zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm);
switch (backend) { switch (backend) {
else => unreachable, else => unreachable,
inline .stage2_aarch64, inline .stage2_arm,
.stage2_arm,
.stage2_riscv64, .stage2_riscv64,
.stage2_sparc64, .stage2_sparc64,
.stage2_x86_64, .stage2_x86_64,
@ -144,8 +141,7 @@ pub fn generateFunction(
const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
switch (target_util.zigBackend(target, false)) { switch (target_util.zigBackend(target, false)) {
else => unreachable, else => unreachable,
inline .stage2_aarch64, inline .stage2_arm,
.stage2_arm,
.stage2_riscv64, .stage2_riscv64,
.stage2_sparc64, .stage2_sparc64,
.stage2_x86_64, .stage2_x86_64,
@ -181,8 +177,7 @@ pub fn emitFunction(
const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
switch (target_util.zigBackend(target, zcu.comp.config.use_llvm)) { switch (target_util.zigBackend(target, zcu.comp.config.use_llvm)) {
else => unreachable, else => unreachable,
inline .stage2_aarch64, inline .stage2_arm,
.stage2_arm,
.stage2_riscv64, .stage2_riscv64,
.stage2_sparc64, .stage2_sparc64,
.stage2_x86_64, .stage2_x86_64,

View file

@ -1,8 +1,7 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
const bits = @import("bits.zig"); const bits = @import("../../arch/aarch64/bits.zig");
const Register = bits.Register; const Register = bits.Register;
const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
const Type = @import("../../Type.zig"); const Type = @import("../../Type.zig");
const Zcu = @import("../../Zcu.zig"); const Zcu = @import("../../Zcu.zig");
@ -149,17 +148,3 @@ pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6,
pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 }; pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
const allocatable_registers = callee_preserved_regs; const allocatable_registers = callee_preserved_regs;
pub const RegisterManager = RegisterManagerFn(@import("CodeGen.zig"), Register, &allocatable_registers);
// Register classes
const RegisterBitSet = RegisterManager.RegisterBitSet;
pub const RegisterClass = struct {
pub const gp: RegisterBitSet = blk: {
var set = RegisterBitSet.initEmpty();
for (callee_preserved_regs) |reg| {
const index = RegisterManager.indexOfRegIntoTracked(reg).?;
set.set(index);
}
break :blk set;
};
};

View file

@ -22,7 +22,7 @@ const Value = @import("../Value.zig");
const Type = @import("../Type.zig"); const Type = @import("../Type.zig");
const x86_64_abi = @import("../arch/x86_64/abi.zig"); const x86_64_abi = @import("../arch/x86_64/abi.zig");
const wasm_c_abi = @import("../arch/wasm/abi.zig"); const wasm_c_abi = @import("../arch/wasm/abi.zig");
const aarch64_c_abi = @import("../arch/aarch64/abi.zig"); const aarch64_c_abi = @import("aarch64/abi.zig");
const arm_c_abi = @import("../arch/arm/abi.zig"); const arm_c_abi = @import("../arch/arm/abi.zig");
const riscv_c_abi = @import("../arch/riscv64/abi.zig"); const riscv_c_abi = @import("../arch/riscv64/abi.zig");
const mips_c_abi = @import("../arch/mips/abi.zig"); const mips_c_abi = @import("../arch/mips/abi.zig");