mirror of
https://github.com/ziglang/zig.git
synced 2026-01-03 03:53:20 +00:00
stage2 aarch64: add PC relative address instructions
This commit is contained in:
parent
a0226ab05b
commit
5ff8dd179e
@ -203,6 +203,13 @@ pub const Instruction = union(enum) {
|
||||
opc: u2,
|
||||
sf: u1,
|
||||
},
|
||||
PCRelativeAddress: packed struct {
|
||||
rd: u5,
|
||||
immhi: u19,
|
||||
fixed: u5 = 0b10000,
|
||||
immlo: u2,
|
||||
op: u1,
|
||||
},
|
||||
LoadStoreRegister: packed struct {
|
||||
rt: u5,
|
||||
rn: u5,
|
||||
@ -245,6 +252,7 @@ pub const Instruction = union(enum) {
|
||||
pub fn toU32(self: Instruction) u32 {
|
||||
return switch (self) {
|
||||
.MoveWideImmediate => |v| @bitCast(u32, v),
|
||||
.PCRelativeAddress => |v| @bitCast(u32, v),
|
||||
.LoadStoreRegister => |v| @bitCast(u32, v),
|
||||
.LoadLiteral => |v| @bitCast(u32, v),
|
||||
.ExceptionGeneration => |v| @bitCast(u32, v),
|
||||
@ -408,6 +416,18 @@ pub const Instruction = union(enum) {
|
||||
}
|
||||
}
|
||||
|
||||
fn pcRelativeAddress(rd: Register, imm21: i21, op: u1) Instruction {
|
||||
const imm21_u = @bitCast(u21, imm21);
|
||||
return Instruction{
|
||||
.PCRelativeAddress = .{
|
||||
.rd = rd.id(),
|
||||
.immlo = @truncate(u2, imm21_u),
|
||||
.immhi = @truncate(u19, imm21_u >> 2),
|
||||
.op = op,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn loadStoreRegister(rt: Register, rn: Register, offset: Offset, load: bool) Instruction {
|
||||
const off = offset.toU12();
|
||||
const op1: u2 = blk: {
|
||||
@ -536,6 +556,16 @@ pub const Instruction = union(enum) {
|
||||
return moveWideImmediate(0b11, rd, imm16, shift);
|
||||
}
|
||||
|
||||
// PC relative address
|
||||
|
||||
pub fn adr(rd: Register, imm21: i21) Instruction {
|
||||
return pcRelativeAddress(rd, imm21, 0b0);
|
||||
}
|
||||
|
||||
pub fn adrp(rd: Register, imm21: i21) Instruction {
|
||||
return pcRelativeAddress(rd, imm21, 0b1);
|
||||
}
|
||||
|
||||
// Load or store register
|
||||
|
||||
pub const LdrArgs = struct {
|
||||
@ -690,6 +720,22 @@ test "serialize instructions" {
|
||||
.inst = Instruction.str(.x2, .x1, .{ .offset = Instruction.Offset.reg(.x3) }),
|
||||
.expected = 0b11_111_0_00_00_1_00011_011_0_10_00001_00010,
|
||||
},
|
||||
.{ // adr x2, #0x8
|
||||
.inst = Instruction.adr(.x2, 0x8),
|
||||
.expected = 0b0_00_10000_0000000000000000010_00010,
|
||||
},
|
||||
.{ // adr x2, -#0x8
|
||||
.inst = Instruction.adr(.x2, -0x8),
|
||||
.expected = 0b0_00_10000_1111111111111111110_00010,
|
||||
},
|
||||
.{ // adrp x2, #0x8
|
||||
.inst = Instruction.adrp(.x2, 0x8),
|
||||
.expected = 0b1_00_10000_0000000000000000010_00010,
|
||||
},
|
||||
.{ // adrp x2, -#0x8
|
||||
.inst = Instruction.adrp(.x2, -0x8),
|
||||
.expected = 0b1_00_10000_1111111111111111110_00010,
|
||||
},
|
||||
};
|
||||
|
||||
for (testcases) |case| {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user