mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 13:30:45 +00:00
Merge pull request #11923 from koachan/sparc64-codegen
stage2: sparc64: Another batch of new Air lowerings, improvements, and fixes
This commit is contained in:
commit
905a18849f
File diff suppressed because it is too large
Load Diff
@ -93,13 +93,20 @@ pub fn emitMir(
|
||||
.lduw => try emit.mirArithmetic3Op(inst),
|
||||
.ldx => try emit.mirArithmetic3Op(inst),
|
||||
|
||||
.@"and" => try emit.mirArithmetic3Op(inst),
|
||||
.@"or" => try emit.mirArithmetic3Op(inst),
|
||||
.xor => try emit.mirArithmetic3Op(inst),
|
||||
.xnor => try emit.mirArithmetic3Op(inst),
|
||||
|
||||
.membar => try emit.mirMembar(inst),
|
||||
|
||||
.movcc => try emit.mirConditionalMove(inst),
|
||||
|
||||
.movr => try emit.mirConditionalMove(inst),
|
||||
|
||||
.mulx => try emit.mirArithmetic3Op(inst),
|
||||
.sdivx => try emit.mirArithmetic3Op(inst),
|
||||
.udivx => try emit.mirArithmetic3Op(inst),
|
||||
|
||||
.nop => try emit.mirNop(),
|
||||
|
||||
@ -110,12 +117,12 @@ pub fn emitMir(
|
||||
|
||||
.sethi => try emit.mirSethi(inst),
|
||||
|
||||
.sll => @panic("TODO implement sparc64 sll"),
|
||||
.srl => @panic("TODO implement sparc64 srl"),
|
||||
.sra => @panic("TODO implement sparc64 sra"),
|
||||
.sllx => @panic("TODO implement sparc64 sllx"),
|
||||
.srlx => @panic("TODO implement sparc64 srlx"),
|
||||
.srax => @panic("TODO implement sparc64 srax"),
|
||||
.sll => try emit.mirShift(inst),
|
||||
.srl => try emit.mirShift(inst),
|
||||
.sra => try emit.mirShift(inst),
|
||||
.sllx => try emit.mirShift(inst),
|
||||
.srlx => try emit.mirShift(inst),
|
||||
.srax => try emit.mirShift(inst),
|
||||
|
||||
.stb => try emit.mirArithmetic3Op(inst),
|
||||
.sth => try emit.mirArithmetic3Op(inst),
|
||||
@ -201,7 +208,7 @@ fn mirArithmetic2Op(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
.@"return" => try emit.writeInstruction(Instruction.@"return"(Register, rs1, rs2)),
|
||||
.cmp => try emit.writeInstruction(Instruction.subcc(Register, rs1, rs2, .g0)),
|
||||
.mov => try emit.writeInstruction(Instruction.@"or"(Register, .g0, rs2, rs1)),
|
||||
.not => try emit.writeInstruction(Instruction.xnor(Register, .g0, rs2, rs1)),
|
||||
.not => try emit.writeInstruction(Instruction.xnor(Register, rs2, .g0, rs1)),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
@ -224,10 +231,13 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
.lduh => try emit.writeInstruction(Instruction.lduh(i13, rs1, imm, rd)),
|
||||
.lduw => try emit.writeInstruction(Instruction.lduw(i13, rs1, imm, rd)),
|
||||
.ldx => try emit.writeInstruction(Instruction.ldx(i13, rs1, imm, rd)),
|
||||
.@"and" => try emit.writeInstruction(Instruction.@"and"(i13, rs1, imm, rd)),
|
||||
.@"or" => try emit.writeInstruction(Instruction.@"or"(i13, rs1, imm, rd)),
|
||||
.xor => try emit.writeInstruction(Instruction.xor(i13, rs1, imm, rd)),
|
||||
.xnor => try emit.writeInstruction(Instruction.xnor(i13, rs1, imm, rd)),
|
||||
.mulx => try emit.writeInstruction(Instruction.mulx(i13, rs1, imm, rd)),
|
||||
.sdivx => try emit.writeInstruction(Instruction.sdivx(i13, rs1, imm, rd)),
|
||||
.udivx => try emit.writeInstruction(Instruction.udivx(i13, rs1, imm, rd)),
|
||||
.save => try emit.writeInstruction(Instruction.save(i13, rs1, imm, rd)),
|
||||
.restore => try emit.writeInstruction(Instruction.restore(i13, rs1, imm, rd)),
|
||||
.stb => try emit.writeInstruction(Instruction.stb(i13, rs1, imm, rd)),
|
||||
@ -248,10 +258,13 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
.lduh => try emit.writeInstruction(Instruction.lduh(Register, rs1, rs2, rd)),
|
||||
.lduw => try emit.writeInstruction(Instruction.lduw(Register, rs1, rs2, rd)),
|
||||
.ldx => try emit.writeInstruction(Instruction.ldx(Register, rs1, rs2, rd)),
|
||||
.@"and" => try emit.writeInstruction(Instruction.@"and"(Register, rs1, rs2, rd)),
|
||||
.@"or" => try emit.writeInstruction(Instruction.@"or"(Register, rs1, rs2, rd)),
|
||||
.xor => try emit.writeInstruction(Instruction.xor(Register, rs1, rs2, rd)),
|
||||
.xnor => try emit.writeInstruction(Instruction.xnor(Register, rs1, rs2, rd)),
|
||||
.mulx => try emit.writeInstruction(Instruction.mulx(Register, rs1, rs2, rd)),
|
||||
.sdivx => try emit.writeInstruction(Instruction.sdivx(Register, rs1, rs2, rd)),
|
||||
.udivx => try emit.writeInstruction(Instruction.udivx(Register, rs1, rs2, rd)),
|
||||
.save => try emit.writeInstruction(Instruction.save(Register, rs1, rs2, rd)),
|
||||
.restore => try emit.writeInstruction(Instruction.restore(Register, rs1, rs2, rd)),
|
||||
.stb => try emit.writeInstruction(Instruction.stb(Register, rs1, rs2, rd)),
|
||||
@ -314,7 +327,7 @@ fn mirConditionalMove(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
|
||||
switch (tag) {
|
||||
.movcc => {
|
||||
const data = emit.mir.instructions.items(.data)[inst].conditional_move;
|
||||
const data = emit.mir.instructions.items(.data)[inst].conditional_move_int;
|
||||
if (data.is_imm) {
|
||||
try emit.writeInstruction(Instruction.movcc(
|
||||
i11,
|
||||
@ -333,10 +346,41 @@ fn mirConditionalMove(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
));
|
||||
}
|
||||
},
|
||||
.movr => {
|
||||
const data = emit.mir.instructions.items(.data)[inst].conditional_move_reg;
|
||||
if (data.is_imm) {
|
||||
try emit.writeInstruction(Instruction.movr(
|
||||
i10,
|
||||
data.cond,
|
||||
data.rs1,
|
||||
data.rs2_or_imm.imm,
|
||||
data.rd,
|
||||
));
|
||||
} else {
|
||||
try emit.writeInstruction(Instruction.movr(
|
||||
Register,
|
||||
data.cond,
|
||||
data.rs1,
|
||||
data.rs2_or_imm.rs2,
|
||||
data.rd,
|
||||
));
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn mirMembar(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const tag = emit.mir.instructions.items(.tag)[inst];
|
||||
const mask = emit.mir.instructions.items(.data)[inst].membar_mask;
|
||||
assert(tag == .membar);
|
||||
|
||||
try emit.writeInstruction(Instruction.membar(
|
||||
mask.cmask,
|
||||
mask.mmask,
|
||||
));
|
||||
}
|
||||
|
||||
fn mirNop(emit: *Emit) !void {
|
||||
try emit.writeInstruction(Instruction.nop());
|
||||
}
|
||||
@ -352,6 +396,38 @@ fn mirSethi(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
try emit.writeInstruction(Instruction.sethi(imm, rd));
|
||||
}
|
||||
|
||||
fn mirShift(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const tag = emit.mir.instructions.items(.tag)[inst];
|
||||
const data = emit.mir.instructions.items(.data)[inst].shift;
|
||||
|
||||
const rd = data.rd;
|
||||
const rs1 = data.rs1;
|
||||
|
||||
if (data.is_imm) {
|
||||
const imm = data.rs2_or_imm.imm;
|
||||
switch (tag) {
|
||||
.sll => try emit.writeInstruction(Instruction.sll(u5, rs1, @truncate(u5, imm), rd)),
|
||||
.srl => try emit.writeInstruction(Instruction.srl(u5, rs1, @truncate(u5, imm), rd)),
|
||||
.sra => try emit.writeInstruction(Instruction.sra(u5, rs1, @truncate(u5, imm), rd)),
|
||||
.sllx => try emit.writeInstruction(Instruction.sllx(u6, rs1, imm, rd)),
|
||||
.srlx => try emit.writeInstruction(Instruction.srlx(u6, rs1, imm, rd)),
|
||||
.srax => try emit.writeInstruction(Instruction.srax(u6, rs1, imm, rd)),
|
||||
else => unreachable,
|
||||
}
|
||||
} else {
|
||||
const rs2 = data.rs2_or_imm.rs2;
|
||||
switch (tag) {
|
||||
.sll => try emit.writeInstruction(Instruction.sll(Register, rs1, rs2, rd)),
|
||||
.srl => try emit.writeInstruction(Instruction.srl(Register, rs1, rs2, rd)),
|
||||
.sra => try emit.writeInstruction(Instruction.sra(Register, rs1, rs2, rd)),
|
||||
.sllx => try emit.writeInstruction(Instruction.sllx(Register, rs1, rs2, rd)),
|
||||
.srlx => try emit.writeInstruction(Instruction.srlx(Register, rs1, rs2, rd)),
|
||||
.srax => try emit.writeInstruction(Instruction.srax(Register, rs1, rs2, rd)),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mirTrap(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const tag = emit.mir.instructions.items(.tag)[inst];
|
||||
const data = emit.mir.instructions.items(.data)[inst].trap;
|
||||
|
||||
@ -73,18 +73,28 @@ pub const Inst = struct {
|
||||
/// A.31 Logical Operations
|
||||
/// This uses the arithmetic_3op field.
|
||||
// TODO add other operations.
|
||||
@"and",
|
||||
@"or",
|
||||
xor,
|
||||
xnor,
|
||||
|
||||
/// A.32 Memory Barrier
|
||||
/// This uses the membar_mask field.
|
||||
membar,
|
||||
|
||||
/// A.35 Move Integer Register on Condition (MOVcc)
|
||||
/// This uses the conditional_move field.
|
||||
/// This uses the conditional_move_int field.
|
||||
movcc,
|
||||
|
||||
/// A.36 Move Integer Register on Register Condition (MOVr)
|
||||
/// This uses the conditional_move_reg field.
|
||||
movr,
|
||||
|
||||
/// A.37 Multiply and Divide (64-bit)
|
||||
/// This uses the arithmetic_3op field.
|
||||
// TODO add other operations.
|
||||
mulx,
|
||||
sdivx,
|
||||
udivx,
|
||||
|
||||
/// A.40 No Operation
|
||||
/// This uses the nop field.
|
||||
@ -154,8 +164,9 @@ pub const Inst = struct {
|
||||
/// This uses the arithmetic_2op field, with rs1
|
||||
/// being the *destination* register.
|
||||
// TODO is it okay to abuse rs1 in this way?
|
||||
// TODO this differs from official encoding for convenience, fix it later
|
||||
not, // not rs2/imm, rs1 -> xnor %g0, rs2/imm, rs1
|
||||
// not rs2, rs1 -> xnor rs2, %g0, rs1
|
||||
// not imm, rs1 -> xnor %g0, imm, rs1
|
||||
not,
|
||||
};
|
||||
|
||||
/// The position of an MIR instruction within the `Mir` instructions array.
|
||||
@ -230,12 +241,19 @@ pub const Inst = struct {
|
||||
inst: Index,
|
||||
},
|
||||
|
||||
/// Conditional move.
|
||||
/// Membar mask, controls the barrier behavior
|
||||
/// Used by e.g. membar
|
||||
membar_mask: struct {
|
||||
mmask: Instruction.MemOrderingConstraint = .{},
|
||||
cmask: Instruction.MemCompletionConstraint = .{},
|
||||
},
|
||||
|
||||
/// Conditional move, checking the integer status code
|
||||
/// if is_imm true then it uses the imm field of rs2_or_imm,
|
||||
/// otherwise it uses rs2 field.
|
||||
///
|
||||
/// Used by e.g. movcc
|
||||
conditional_move: struct {
|
||||
conditional_move_int: struct {
|
||||
is_imm: bool,
|
||||
ccr: Instruction.CCR,
|
||||
cond: Instruction.Condition,
|
||||
@ -246,6 +264,22 @@ pub const Inst = struct {
|
||||
},
|
||||
},
|
||||
|
||||
/// Conditional move, comparing a register's content with zero
|
||||
/// if is_imm true then it uses the imm field of rs2_or_imm,
|
||||
/// otherwise it uses rs2 field.
|
||||
///
|
||||
/// Used by e.g. movr
|
||||
conditional_move_reg: struct {
|
||||
is_imm: bool,
|
||||
cond: Instruction.RCondition,
|
||||
rd: Register,
|
||||
rs1: Register,
|
||||
rs2_or_imm: union {
|
||||
rs2: Register,
|
||||
imm: i10,
|
||||
},
|
||||
},
|
||||
|
||||
/// No additional data
|
||||
///
|
||||
/// Used by e.g. flushw
|
||||
@ -266,7 +300,6 @@ pub const Inst = struct {
|
||||
/// Used by e.g. sllx
|
||||
shift: struct {
|
||||
is_imm: bool,
|
||||
width: Instruction.ShiftWidth,
|
||||
rd: Register,
|
||||
rs1: Register,
|
||||
rs2_or_imm: union {
|
||||
|
||||
@ -475,6 +475,21 @@ pub const Instruction = union(enum) {
|
||||
ne_zero,
|
||||
gt_zero,
|
||||
ge_zero,
|
||||
|
||||
/// Returns the condition which is true iff the given condition is
|
||||
/// false (if such a condition exists).
|
||||
pub fn negate(cond: RCondition) RCondition {
|
||||
return switch (cond) {
|
||||
.eq_zero => .ne_zero,
|
||||
.ne_zero => .eq_zero,
|
||||
.lt_zero => .ge_zero,
|
||||
.ge_zero => .lt_zero,
|
||||
.le_zero => .gt_zero,
|
||||
.gt_zero => .le_zero,
|
||||
.reserved1 => unreachable,
|
||||
.reserved2 => unreachable,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const ASI = enum(u8) {
|
||||
@ -673,10 +688,27 @@ pub const Instruction = union(enum) {
|
||||
}
|
||||
};
|
||||
|
||||
pub const Condition = packed union {
|
||||
pub const ConditionTag = enum { fcond, icond };
|
||||
pub const Condition = union(ConditionTag) {
|
||||
fcond: FCondition,
|
||||
icond: ICondition,
|
||||
encoded: u4,
|
||||
|
||||
/// Encodes the condition into the instruction bit pattern.
|
||||
pub fn enc(cond: Condition) u4 {
|
||||
return switch (cond) {
|
||||
.icond => |c| @enumToInt(c),
|
||||
.fcond => |c| @enumToInt(c),
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the condition which is true iff the given condition is
|
||||
/// false (if such a condition exists).
|
||||
pub fn negate(cond: Condition) Condition {
|
||||
return switch (cond) {
|
||||
.icond => |c| .{ .icond = c.negate() },
|
||||
.fcond => |c| .{ .fcond = c.negate() },
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn toU32(self: Instruction) u32 {
|
||||
@ -755,7 +787,7 @@ pub const Instruction = union(enum) {
|
||||
return Instruction{
|
||||
.format_2b = .{
|
||||
.a = @boolToInt(annul),
|
||||
.cond = cond.encoded,
|
||||
.cond = cond.enc(),
|
||||
.op2 = op2,
|
||||
.disp22 = udisp_truncated,
|
||||
},
|
||||
@ -776,7 +808,7 @@ pub const Instruction = union(enum) {
|
||||
return Instruction{
|
||||
.format_2c = .{
|
||||
.a = @boolToInt(annul),
|
||||
.cond = cond.encoded,
|
||||
.cond = cond.enc(),
|
||||
.op2 = op2,
|
||||
.cc1 = ccr_cc1,
|
||||
.cc0 = ccr_cc0,
|
||||
@ -1057,7 +1089,7 @@ pub const Instruction = union(enum) {
|
||||
.rd = rd.enc(),
|
||||
.op3 = op3,
|
||||
.cc2 = ccr_cc2,
|
||||
.cond = cond.encoded,
|
||||
.cond = cond.enc(),
|
||||
.cc1 = ccr_cc1,
|
||||
.cc0 = ccr_cc0,
|
||||
.rs2 = rs2.enc(),
|
||||
@ -1074,7 +1106,7 @@ pub const Instruction = union(enum) {
|
||||
.rd = rd.enc(),
|
||||
.op3 = op3,
|
||||
.cc2 = ccr_cc2,
|
||||
.cond = cond.encoded,
|
||||
.cond = cond.enc(),
|
||||
.cc1 = ccr_cc1,
|
||||
.cc0 = ccr_cc0,
|
||||
.simm11 = @bitCast(u11, imm),
|
||||
@ -1122,7 +1154,7 @@ pub const Instruction = union(enum) {
|
||||
.format_4g = .{
|
||||
.rd = rd.enc(),
|
||||
.op3 = op3,
|
||||
.cond = cond.encoded,
|
||||
.cond = cond.enc(),
|
||||
.opf_cc = opf_cc,
|
||||
.opf_low = opf_low,
|
||||
.rs2 = rs2.enc(),
|
||||
@ -1197,6 +1229,14 @@ pub const Instruction = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn @"and"(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b10, 0b00_0001, rs1, rs2, rd),
|
||||
i13 => format3b(0b10, 0b00_0001, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn @"or"(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b10, 0b00_0010, rs1, rs2, rd),
|
||||
@ -1221,6 +1261,10 @@ pub const Instruction = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn membar(cmask: MemCompletionConstraint, mmask: MemOrderingConstraint) Instruction {
|
||||
return format3h(cmask, mmask);
|
||||
}
|
||||
|
||||
pub fn movcc(comptime s2: type, cond: Condition, ccr: CCR, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format4c(0b10_1100, cond, ccr, rs2, rd),
|
||||
@ -1229,6 +1273,14 @@ pub const Instruction = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn movr(comptime s2: type, cond: RCondition, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3e(0b10, 0b10_1111, cond, rs1, rs2, rd),
|
||||
i10 => format3f(0b10, 0b10_1111, cond, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn mulx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b10, 0b00_1001, rs1, rs2, rd),
|
||||
@ -1237,6 +1289,22 @@ pub const Instruction = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn sdivx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b10, 0b10_1101, rs1, rs2, rd),
|
||||
i13 => format3b(0b10, 0b10_1101, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn udivx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b10, 0b00_1101, rs1, rs2, rd),
|
||||
i13 => format3b(0b10, 0b00_1101, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn nop() Instruction {
|
||||
return sethi(0, .g0);
|
||||
}
|
||||
@ -1269,6 +1337,54 @@ pub const Instruction = union(enum) {
|
||||
return format2a(0b100, imm, rd);
|
||||
}
|
||||
|
||||
pub fn sll(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0101, .shift32, rs1, rs2, rd),
|
||||
u5 => format3l(0b11, 0b10_0101, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn srl(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0110, .shift32, rs1, rs2, rd),
|
||||
u5 => format3l(0b11, 0b10_0110, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn sra(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0111, .shift32, rs1, rs2, rd),
|
||||
u5 => format3l(0b11, 0b10_0111, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn sllx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0101, .shift64, rs1, rs2, rd),
|
||||
u6 => format3m(0b11, 0b10_0101, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn srlx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0110, .shift64, rs1, rs2, rd),
|
||||
u6 => format3m(0b11, 0b10_0110, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn srax(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3k(0b11, 0b10_0111, .shift64, rs1, rs2, rd),
|
||||
u6 => format3m(0b11, 0b10_0111, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn stb(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b11, 0b00_0101, rs1, rs2, rd),
|
||||
|
||||
@ -511,6 +511,7 @@ test "zero-sized array with recursive type definition" {
|
||||
|
||||
test "type coercion of anon struct literal to array" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ test "cmpxchg" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testCmpxchg();
|
||||
@ -48,6 +49,7 @@ test "atomicrmw and atomicload" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
var data: u8 = 200;
|
||||
@ -77,6 +79,7 @@ test "cmpxchg with ptr" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
var data1: i32 = 1234;
|
||||
@ -103,6 +106,7 @@ test "cmpxchg with ignored result" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
var x: i32 = 1234;
|
||||
@ -117,6 +121,7 @@ test "128-bit cmpxchg" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
if (builtin.cpu.arch != .x86_64) return error.SkipZigTest;
|
||||
@ -150,6 +155,7 @@ test "cmpxchg on a global variable" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm) and
|
||||
@ -168,6 +174,7 @@ test "atomic load and rmw with enum" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const Value = enum(u8) { a, b, c };
|
||||
@ -186,6 +193,7 @@ test "atomic store" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
var x: u32 = 0;
|
||||
@ -200,6 +208,7 @@ test "atomic store comptime" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testAtomicStore();
|
||||
@ -219,6 +228,7 @@ test "atomicrmw with floats" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm) and
|
||||
@ -247,6 +257,7 @@ test "atomicrmw with ints" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testAtomicRmwInt();
|
||||
@ -281,6 +292,7 @@ test "atomics with different types" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testAtomicsWithType(bool, true, false);
|
||||
@ -311,6 +323,7 @@ test "return @atomicStore, using it as a void value" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
|
||||
@ -24,6 +24,8 @@ fn testTruncate(x: u32) u8 {
|
||||
}
|
||||
|
||||
test "truncate to non-power-of-two integers" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testTrunc(u32, u1, 0b10101, 0b1);
|
||||
try testTrunc(u32, u1, 0b10110, 0b0);
|
||||
try testTrunc(u32, u2, 0b10101, 0b01);
|
||||
@ -401,6 +403,7 @@ fn testPointerToVoidReturnType2() *const void {
|
||||
|
||||
test "array 2D const double ptr" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
@ -414,6 +417,7 @@ test "array 2D const double ptr" {
|
||||
|
||||
test "array 2D const double ptr with offset" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
@ -427,6 +431,7 @@ test "array 2D const double ptr with offset" {
|
||||
|
||||
test "array 3D const double ptr with offset" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -46,6 +46,7 @@ test {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ test "@byteSwap integers" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
|
||||
|
||||
const ByteSwapIntTest = struct {
|
||||
fn run() !void {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user