stage2 AArch64: Add madd, msub, mul, mneg instructions

This commit is contained in:
joachimschmidt557 2022-02-05 18:45:35 +01:00
parent 77cf000438
commit 82f91adbb4
No known key found for this signature in database
GPG Key ID: E0B575BE2884ACC5

View File

@ -332,6 +332,17 @@ pub const Instruction = union(enum) {
op: u1,
sf: u1,
},
data_processing_3_source: packed struct {
rd: u5,
rn: u5,
ra: u5,
o0: u1,
rm: u5,
op31: u3,
fixed: u5 = 0b11011,
op54: u2,
sf: u1,
},
pub const Shift = struct {
shift: Type = .lsl,
@ -470,6 +481,7 @@ pub const Instruction = union(enum) {
.conditional_branch => |v| @as(u32, v.cond) | (@as(u32, v.o0) << 4) | (@as(u32, v.imm19) << 5) | (@as(u32, v.o1) << 24) | (@as(u32, v.fixed) << 25),
.compare_and_branch => |v| @as(u32, v.rt) | (@as(u32, v.imm19) << 5) | (@as(u32, v.op) << 24) | (@as(u32, v.fixed) << 25) | (@as(u32, v.sf) << 31),
.conditional_select => |v| @as(u32, v.rd) | @as(u32, v.rn) << 5 | @as(u32, v.op2) << 10 | @as(u32, v.cond) << 12 | @as(u32, v.rm) << 16 | @as(u32, v.fixed) << 21 | @as(u32, v.s) << 29 | @as(u32, v.op) << 30 | @as(u32, v.sf) << 31,
.data_processing_3_source => |v| @bitCast(u32, v),
};
}
@ -967,6 +979,33 @@ pub const Instruction = union(enum) {
};
}
fn dataProcessing3Source(
op54: u2,
op31: u3,
o0: u1,
rd: Register,
rn: Register,
rm: Register,
ra: Register,
) Instruction {
return Instruction{
.data_processing_3_source = .{
.rd = rd.id(),
.rn = rn.id(),
.ra = ra.id(),
.o0 = o0,
.rm = rm.id(),
.op31 = op31,
.op54 = op54,
.sf = switch (rd.size()) {
32 => 0b0,
64 => 0b1,
else => unreachable, // unexpected register size
},
},
};
}
// Helper functions for assembly syntax functions
// Move wide (immediate)
@ -1245,6 +1284,24 @@ pub const Instruction = union(enum) {
pub fn csneg(rd: Register, rn: Register, rm: Register, cond: Condition) Instruction {
return conditionalSelect(0b01, 0b1, 0b0, rd, rn, rm, cond);
}
// Data processing (3 source)
pub fn madd(rd: Register, rn: Register, rm: Register, ra: Register) Instruction {
return dataProcessing3Source(0b00, 0b000, 0b0, rd, rn, rm, ra);
}
pub fn msub(rd: Register, rn: Register, rm: Register, ra: Register) Instruction {
return dataProcessing3Source(0b00, 0b000, 0b1, rd, rn, rm, ra);
}
pub fn mul(rd: Register, rn: Register, rm: Register) Instruction {
return madd(rd, rn, rm, .xzr);
}
pub fn mneg(rd: Register, rn: Register, rm: Register) Instruction {
return msub(rd, rn, rm, .xzr);
}
};
test {
@ -1414,6 +1471,10 @@ test "serialize instructions" {
.inst = Instruction.csinc(.x1, .x2, .x4, .eq),
.expected = 0b1_0_0_11010100_00100_0000_0_1_00010_00001,
},
.{ // mul x1, x4, x9
.inst = Instruction.mul(.x1, .x4, .x9),
.expected = 0b1_00_11011_000_01001_0_11111_00100_00001,
},
};
for (testcases) |case| {