mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 01:15:14 +00:00
x64: handle basic f32 using AVX registers
This commit is contained in:
parent
020f99d893
commit
36b939e8db
@ -3469,22 +3469,28 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu
|
||||
return self.genBinOpMir(mir_tag, dst_ty, dst_mcv, .{ .register = reg });
|
||||
},
|
||||
.register => |src_reg| switch (dst_ty.zigTypeTag()) {
|
||||
.Float => switch (dst_ty.tag()) {
|
||||
.f64 => {
|
||||
_ = try self.addInst(.{
|
||||
.tag = switch (mir_tag) {
|
||||
.add => .add_f64,
|
||||
.cmp => .cmp_f64,
|
||||
else => return self.fail("TODO genBinOpMir for f64 register-register with MIR tag {}", .{mir_tag}),
|
||||
},
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = dst_reg.to128(),
|
||||
.reg2 = src_reg.to128(),
|
||||
}),
|
||||
.data = undefined,
|
||||
});
|
||||
},
|
||||
else => return self.fail("TODO genBinOpMir for float register-register and type {}", .{dst_ty.fmtDebug()}),
|
||||
.Float => {
|
||||
const actual_tag: Mir.Inst.Tag = switch (dst_ty.tag()) {
|
||||
.f32 => switch (mir_tag) {
|
||||
.add => Mir.Inst.Tag.add_f32,
|
||||
.cmp => Mir.Inst.Tag.cmp_f32,
|
||||
else => return self.fail("TODO genBinOpMir for f32 register-register with MIR tag {}", .{mir_tag}),
|
||||
},
|
||||
.f64 => switch (mir_tag) {
|
||||
.add => Mir.Inst.Tag.add_f64,
|
||||
.cmp => Mir.Inst.Tag.cmp_f64,
|
||||
else => return self.fail("TODO genBinOpMir for f64 register-register with MIR tag {}", .{mir_tag}),
|
||||
},
|
||||
else => return self.fail("TODO genBinOpMir for float register-register and type {}", .{dst_ty.fmtDebug()}),
|
||||
};
|
||||
_ = try self.addInst(.{
|
||||
.tag = actual_tag,
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = dst_reg.to128(),
|
||||
.reg2 = src_reg.to128(),
|
||||
}),
|
||||
.data = undefined,
|
||||
});
|
||||
},
|
||||
else => {
|
||||
_ = try self.addInst(.{
|
||||
@ -5475,20 +5481,25 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
|
||||
const base_reg = opts.dest_stack_base orelse .rbp;
|
||||
|
||||
switch (ty.zigTypeTag()) {
|
||||
.Float => switch (ty.tag()) {
|
||||
.f32 => return self.fail("TODO genSetStack for register for f32", .{}),
|
||||
.f64 => {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .mov_f64,
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = base_reg,
|
||||
.reg2 = reg.to128(),
|
||||
.flags = 0b01,
|
||||
}),
|
||||
.data = .{ .imm = @bitCast(u32, -stack_offset) },
|
||||
});
|
||||
},
|
||||
else => return self.fail("TODO genSetStack for register for type {}", .{ty.fmtDebug()}),
|
||||
.Float => {
|
||||
const tag: Mir.Inst.Tag = switch (ty.tag()) {
|
||||
.f32 => .mov_f32,
|
||||
.f64 => .mov_f64,
|
||||
else => return self.fail("TODO genSetStack for register for type {}", .{ty.fmtDebug()}),
|
||||
};
|
||||
_ = try self.addInst(.{
|
||||
.tag = tag,
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = switch (ty.tag()) {
|
||||
.f32 => base_reg.to32(),
|
||||
.f64 => base_reg.to64(),
|
||||
else => unreachable,
|
||||
},
|
||||
.reg2 = reg.to128(),
|
||||
.flags = 0b01,
|
||||
}),
|
||||
.data = .{ .imm = @bitCast(u32, -stack_offset) },
|
||||
});
|
||||
},
|
||||
else => {
|
||||
if (!math.isPowerOfTwo(abi_size)) {
|
||||
@ -5991,21 +6002,22 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
||||
}
|
||||
},
|
||||
},
|
||||
.Float => switch (ty.tag()) {
|
||||
.f32 => return self.fail("TODO genSetReg from register for f32", .{}),
|
||||
.f64 => {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .mov_f64,
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = reg.to128(),
|
||||
.reg2 = src_reg.to128(),
|
||||
.flags = 0b10,
|
||||
}),
|
||||
.data = undefined,
|
||||
});
|
||||
return;
|
||||
},
|
||||
else => return self.fail("TODO genSetReg from register for {}", .{ty.fmtDebug()}),
|
||||
.Float => {
|
||||
const tag: Mir.Inst.Tag = switch (ty.tag()) {
|
||||
.f32 => .mov_f32,
|
||||
.f64 => .mov_f64,
|
||||
else => return self.fail("TODO genSetReg from register for {}", .{ty.fmtDebug()}),
|
||||
};
|
||||
_ = try self.addInst(.{
|
||||
.tag = tag,
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = reg.to128(),
|
||||
.reg2 = src_reg.to128(),
|
||||
.flags = 0b10,
|
||||
}),
|
||||
.data = undefined,
|
||||
});
|
||||
return;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
@ -6035,22 +6047,27 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
||||
},
|
||||
.memory => |x| switch (ty.zigTypeTag()) {
|
||||
.Float => {
|
||||
switch (ty.tag()) {
|
||||
.f32 => return self.fail("TODO genSetReg from memory for f32", .{}),
|
||||
.f64 => {
|
||||
const base_reg = try self.register_manager.allocReg(null, .{ .selector_mask = gp });
|
||||
try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv);
|
||||
_ = try self.addInst(.{
|
||||
.tag = .mov_f64,
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = reg.to128(),
|
||||
.reg2 = base_reg.to64(),
|
||||
}),
|
||||
.data = .{ .imm = 0 },
|
||||
});
|
||||
},
|
||||
const base_reg = try self.register_manager.allocReg(null, .{ .selector_mask = gp });
|
||||
try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv);
|
||||
|
||||
const tag: Mir.Inst.Tag = switch (ty.tag()) {
|
||||
.f32 => .mov_f32,
|
||||
.f64 => .mov_f64,
|
||||
else => return self.fail("TODO genSetReg from memory for {}", .{ty.fmtDebug()}),
|
||||
}
|
||||
};
|
||||
|
||||
_ = try self.addInst(.{
|
||||
.tag = tag,
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = reg.to128(),
|
||||
.reg2 = switch (ty.tag()) {
|
||||
.f32 => base_reg.to32(),
|
||||
.f64 => base_reg.to64(),
|
||||
else => unreachable,
|
||||
},
|
||||
}),
|
||||
.data = .{ .imm = 0 },
|
||||
});
|
||||
},
|
||||
else => {
|
||||
if (x <= math.maxInt(i32)) {
|
||||
@ -6142,20 +6159,25 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
||||
}
|
||||
},
|
||||
},
|
||||
.Float => switch (ty.tag()) {
|
||||
.f32 => return self.fail("TODO genSetReg from stack offset for f32", .{}),
|
||||
.f64 => {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .mov_f64,
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = reg.to128(),
|
||||
.reg2 = .rbp,
|
||||
}),
|
||||
.data = .{ .imm = @bitCast(u32, -off) },
|
||||
});
|
||||
return;
|
||||
},
|
||||
else => return self.fail("TODO genSetReg from stack offset for {}", .{ty.fmtDebug()}),
|
||||
.Float => {
|
||||
const tag: Mir.Inst.Tag = switch (ty.tag()) {
|
||||
.f32 => .mov_f32,
|
||||
.f64 => .mov_f64,
|
||||
else => return self.fail("TODO genSetReg from stack offset for {}", .{ty.fmtDebug()}),
|
||||
};
|
||||
_ = try self.addInst(.{
|
||||
.tag = tag,
|
||||
.ops = Mir.Inst.Ops.encode(.{
|
||||
.reg1 = reg.to128(),
|
||||
.reg2 = switch (ty.tag()) {
|
||||
.f32 => .ebp,
|
||||
.f64 => .rbp,
|
||||
else => unreachable,
|
||||
},
|
||||
}),
|
||||
.data = .{ .imm = @bitCast(u32, -off) },
|
||||
});
|
||||
return;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
@ -183,11 +183,14 @@ pub fn lowerMir(emit: *Emit) InnerError!void {
|
||||
.nop => try emit.mirNop(),
|
||||
|
||||
// AVX instructions
|
||||
.mov_f64 => try emit.mirMovF64(inst),
|
||||
.mov_f64 => try emit.mirMovFloatAvx(.vmovsd, inst),
|
||||
.mov_f32 => try emit.mirMovFloatAvx(.vmovss, inst),
|
||||
|
||||
.add_f64 => try emit.mirAddF64(inst),
|
||||
.add_f64 => try emit.mirAddFloatAvx(.vaddsd, inst),
|
||||
.add_f32 => try emit.mirAddFloatAvx(.vaddss, inst),
|
||||
|
||||
.cmp_f64 => try emit.mirCmpF64(inst),
|
||||
.cmp_f64 => try emit.mirCmpFloatAvx(.vucomisd, inst),
|
||||
.cmp_f32 => try emit.mirCmpFloatAvx(.vucomiss, inst),
|
||||
|
||||
// Pseudo-instructions
|
||||
.call_extern => try emit.mirCallExtern(inst),
|
||||
@ -962,71 +965,48 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
|
||||
|
||||
// AVX instructions
|
||||
|
||||
fn mirMovF64(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
|
||||
const tag = emit.mir.instructions.items(.tag)[inst];
|
||||
assert(tag == .mov_f64);
|
||||
fn mirMovFloatAvx(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
|
||||
const ops = emit.mir.instructions.items(.ops)[inst].decode();
|
||||
|
||||
switch (ops.flags) {
|
||||
0b00 => {
|
||||
const imm = emit.mir.instructions.items(.data)[inst].imm;
|
||||
return lowerToVmEnc(.vmovsd, ops.reg1, RegisterOrMemory.mem(.qword_ptr, .{
|
||||
return lowerToVmEnc(tag, ops.reg1, RegisterOrMemory.mem(Memory.PtrSize.new(ops.reg2.size()), .{
|
||||
.disp = imm,
|
||||
.base = ops.reg2,
|
||||
}), emit.code);
|
||||
},
|
||||
0b01 => {
|
||||
const imm = emit.mir.instructions.items(.data)[inst].imm;
|
||||
return lowerToMvEnc(.vmovsd, RegisterOrMemory.mem(.qword_ptr, .{
|
||||
return lowerToMvEnc(tag, RegisterOrMemory.mem(Memory.PtrSize.new(ops.reg1.size()), .{
|
||||
.disp = imm,
|
||||
.base = ops.reg1,
|
||||
}), ops.reg2, emit.code);
|
||||
},
|
||||
0b10 => {
|
||||
return lowerToRvmEnc(
|
||||
.vmovsd,
|
||||
ops.reg1,
|
||||
ops.reg1,
|
||||
RegisterOrMemory.reg(ops.reg2),
|
||||
emit.code,
|
||||
);
|
||||
return lowerToRvmEnc(tag, ops.reg1, ops.reg1, RegisterOrMemory.reg(ops.reg2), emit.code);
|
||||
},
|
||||
else => return emit.fail("TODO unused variant 0b{b} for mov_f64", .{ops.flags}),
|
||||
}
|
||||
}
|
||||
|
||||
fn mirAddF64(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
|
||||
const tag = emit.mir.instructions.items(.tag)[inst];
|
||||
assert(tag == .add_f64);
|
||||
fn mirAddFloatAvx(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
|
||||
const ops = emit.mir.instructions.items(.ops)[inst].decode();
|
||||
|
||||
switch (ops.flags) {
|
||||
0b00 => {
|
||||
return lowerToRvmEnc(
|
||||
.vaddsd,
|
||||
ops.reg1,
|
||||
ops.reg1,
|
||||
RegisterOrMemory.reg(ops.reg2),
|
||||
emit.code,
|
||||
);
|
||||
return lowerToRvmEnc(tag, ops.reg1, ops.reg1, RegisterOrMemory.reg(ops.reg2), emit.code);
|
||||
},
|
||||
else => return emit.fail("TODO unused variant 0b{b} for mov_f64", .{ops.flags}),
|
||||
}
|
||||
}
|
||||
|
||||
fn mirCmpF64(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
|
||||
const tag = emit.mir.instructions.items(.tag)[inst];
|
||||
assert(tag == .cmp_f64);
|
||||
fn mirCmpFloatAvx(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
|
||||
const ops = emit.mir.instructions.items(.ops)[inst].decode();
|
||||
|
||||
switch (ops.flags) {
|
||||
0b00 => {
|
||||
return lowerToVmEnc(
|
||||
.vucomisd,
|
||||
ops.reg1,
|
||||
RegisterOrMemory.reg(ops.reg2),
|
||||
emit.code,
|
||||
);
|
||||
return lowerToVmEnc(tag, ops.reg1, RegisterOrMemory.reg(ops.reg2), emit.code);
|
||||
},
|
||||
else => return emit.fail("TODO unused variant 0b{b} for mov_f64", .{ops.flags}),
|
||||
}
|
||||
@ -1268,16 +1248,24 @@ const Tag = enum {
|
||||
cmovb,
|
||||
cmovnae,
|
||||
vmovsd,
|
||||
vmovss,
|
||||
vaddsd,
|
||||
vaddss,
|
||||
vcmpsd,
|
||||
vcmpss,
|
||||
vucomisd,
|
||||
vucomiss,
|
||||
|
||||
fn isAvx(tag: Tag) bool {
|
||||
return switch (tag) {
|
||||
.vmovsd,
|
||||
.vmovss,
|
||||
.vaddsd,
|
||||
.vaddss,
|
||||
.vcmpsd,
|
||||
.vcmpss,
|
||||
.vucomisd,
|
||||
.vucomiss,
|
||||
=> true,
|
||||
|
||||
else => false,
|
||||
@ -1406,7 +1394,7 @@ const OpCode = union(enum) {
|
||||
}
|
||||
};
|
||||
|
||||
inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {
|
||||
inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) OpCode {
|
||||
switch (enc) {
|
||||
.zo => return switch (tag) {
|
||||
.ret_near => OpCode.oneByte(0xc3),
|
||||
@ -1416,7 +1404,7 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {
|
||||
.syscall => OpCode.twoByte(0x0f, 0x05),
|
||||
.cbw => OpCode.oneByte(0x98),
|
||||
.cwd, .cdq, .cqo => OpCode.oneByte(0x99),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.d => return switch (tag) {
|
||||
.jmp_near => OpCode.oneByte(0xe9),
|
||||
@ -1437,7 +1425,7 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {
|
||||
.jge, .jnl => if (is_one_byte) OpCode.oneByte(0x7d) else OpCode.twoByte(0x0f, 0x8d),
|
||||
.jle, .jng => if (is_one_byte) OpCode.oneByte(0x7e) else OpCode.twoByte(0x0f, 0x8e),
|
||||
.jg, .jnle => if (is_one_byte) OpCode.oneByte(0x7f) else OpCode.twoByte(0x0f, 0x8f),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.m => return switch (tag) {
|
||||
.jmp_near, .call_near, .push => OpCode.oneByte(0xff),
|
||||
@ -1464,38 +1452,38 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {
|
||||
.fisttp64 => OpCode.oneByte(0xdd),
|
||||
.fld32 => OpCode.oneByte(0xd9),
|
||||
.fld64 => OpCode.oneByte(0xdd),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.o => return switch (tag) {
|
||||
.push => OpCode.oneByte(0x50),
|
||||
.pop => OpCode.oneByte(0x58),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.i => return switch (tag) {
|
||||
.push => OpCode.oneByte(if (is_one_byte) 0x6a else 0x68),
|
||||
.@"test" => OpCode.oneByte(if (is_one_byte) 0xa8 else 0xa9),
|
||||
.ret_near => OpCode.oneByte(0xc2),
|
||||
.ret_far => OpCode.oneByte(0xca),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.m1 => return switch (tag) {
|
||||
.shl, .sal, .shr, .sar => OpCode.oneByte(if (is_one_byte) 0xd0 else 0xd1),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.mc => return switch (tag) {
|
||||
.shl, .sal, .shr, .sar => OpCode.oneByte(if (is_one_byte) 0xd2 else 0xd3),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.mi => return switch (tag) {
|
||||
.adc, .add, .sub, .xor, .@"and", .@"or", .sbb, .cmp => OpCode.oneByte(if (is_one_byte) 0x80 else 0x81),
|
||||
.mov => OpCode.oneByte(if (is_one_byte) 0xc6 else 0xc7),
|
||||
.@"test" => OpCode.oneByte(if (is_one_byte) 0xf6 else 0xf7),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.mi8 => return switch (tag) {
|
||||
.adc, .add, .sub, .xor, .@"and", .@"or", .sbb, .cmp => OpCode.oneByte(0x83),
|
||||
.shl, .sal, .shr, .sar => OpCode.oneByte(if (is_one_byte) 0xc0 else 0xc1),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.mr => return switch (tag) {
|
||||
.adc => OpCode.oneByte(if (is_one_byte) 0x10 else 0x11),
|
||||
@ -1508,8 +1496,7 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {
|
||||
.cmp => OpCode.oneByte(if (is_one_byte) 0x38 else 0x39),
|
||||
.mov => OpCode.oneByte(if (is_one_byte) 0x88 else 0x89),
|
||||
.@"test" => OpCode.oneByte(if (is_one_byte) 0x84 else 0x85),
|
||||
.vmovsd => OpCode.oneByte(0x11),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.rm => return switch (tag) {
|
||||
.adc => OpCode.oneByte(if (is_one_byte) 0x12 else 0x13),
|
||||
@ -1529,48 +1516,46 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {
|
||||
.cmove, .cmovz => OpCode.twoByte(0x0f, 0x44),
|
||||
.cmovb, .cmovnae => OpCode.twoByte(0x0f, 0x42),
|
||||
.cmovl, .cmovng => OpCode.twoByte(0x0f, 0x4c),
|
||||
.vmovsd => OpCode.oneByte(0x10),
|
||||
.vucomisd => OpCode.oneByte(0x2e),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.oi => return switch (tag) {
|
||||
.mov => OpCode.oneByte(if (is_one_byte) 0xb0 else 0xb8),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.fd => return switch (tag) {
|
||||
.mov => OpCode.oneByte(if (is_one_byte) 0xa0 else 0xa1),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.td => return switch (tag) {
|
||||
.mov => OpCode.oneByte(if (is_one_byte) 0xa2 else 0xa3),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.rmi => return switch (tag) {
|
||||
.imul => OpCode.oneByte(if (is_one_byte) 0x6b else 0x69),
|
||||
else => null,
|
||||
else => unreachable,
|
||||
},
|
||||
.mv => return switch (tag) {
|
||||
.vmovsd => OpCode.oneByte(0x11),
|
||||
else => null,
|
||||
.vmovsd, .vmovss => OpCode.oneByte(0x11),
|
||||
else => unreachable,
|
||||
},
|
||||
.vm => return switch (tag) {
|
||||
.vmovsd => OpCode.oneByte(0x10),
|
||||
.vucomisd => OpCode.oneByte(0x2e),
|
||||
else => null,
|
||||
.vmovsd, .vmovss => OpCode.oneByte(0x10),
|
||||
.vucomisd, .vucomiss => OpCode.oneByte(0x2e),
|
||||
else => unreachable,
|
||||
},
|
||||
.rvm => return switch (tag) {
|
||||
.vaddsd => OpCode.oneByte(0x58),
|
||||
.vmovsd => OpCode.oneByte(0x10),
|
||||
else => null,
|
||||
.vaddsd, .vaddss => OpCode.oneByte(0x58),
|
||||
.vmovsd, .vmovss => OpCode.oneByte(0x10),
|
||||
else => unreachable,
|
||||
},
|
||||
.rvmi => return switch (tag) {
|
||||
.vcmpsd => OpCode.oneByte(0xc2),
|
||||
else => null,
|
||||
.vcmpsd, .vcmpss => OpCode.oneByte(0xc2),
|
||||
else => unreachable,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
inline fn getModRmExt(tag: Tag) ?u3 {
|
||||
inline fn getModRmExt(tag: Tag) u3 {
|
||||
return switch (tag) {
|
||||
.adc => 0x2,
|
||||
.add => 0x0,
|
||||
@ -1631,11 +1616,11 @@ inline fn getModRmExt(tag: Tag) ?u3 {
|
||||
.fisttp64 => 0x1,
|
||||
.fld32 => 0x0,
|
||||
.fld64 => 0x0,
|
||||
else => null,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
const VexPrefix = struct {
|
||||
const VexEncoding = struct {
|
||||
prefix: Encoder.Vex,
|
||||
reg: ?enum {
|
||||
ndd,
|
||||
@ -1644,7 +1629,7 @@ const VexPrefix = struct {
|
||||
},
|
||||
};
|
||||
|
||||
inline fn getVexPrefix(tag: Tag, enc: Encoding) ?VexPrefix {
|
||||
inline fn getVexEncoding(tag: Tag, enc: Encoding) VexEncoding {
|
||||
const desc: struct {
|
||||
reg: enum {
|
||||
none,
|
||||
@ -1671,21 +1656,27 @@ inline fn getVexPrefix(tag: Tag, enc: Encoding) ?VexPrefix {
|
||||
switch (enc) {
|
||||
.mv => switch (tag) {
|
||||
.vmovsd => break :blk .{ .lig = true, .simd_prefix = .p_f2, .wig = true },
|
||||
else => return null,
|
||||
.vmovss => break :blk .{ .lig = true, .simd_prefix = .p_f3, .wig = true },
|
||||
else => unreachable,
|
||||
},
|
||||
.vm => switch (tag) {
|
||||
.vmovsd => break :blk .{ .lig = true, .simd_prefix = .p_f2, .wig = true },
|
||||
.vmovss => break :blk .{ .lig = true, .simd_prefix = .p_f3, .wig = true },
|
||||
.vucomisd => break :blk .{ .lig = true, .simd_prefix = .p_66, .wig = true },
|
||||
else => return null,
|
||||
.vucomiss => break :blk .{ .lig = true, .wig = true },
|
||||
else => unreachable,
|
||||
},
|
||||
.rvm => switch (tag) {
|
||||
.vaddsd => break :blk .{ .reg = .nds, .lig = true, .simd_prefix = .p_f2, .wig = true },
|
||||
.vaddss => break :blk .{ .reg = .nds, .lig = true, .simd_prefix = .p_f3, .wig = true },
|
||||
.vmovsd => break :blk .{ .reg = .nds, .lig = true, .simd_prefix = .p_f2, .wig = true },
|
||||
else => return null,
|
||||
.vmovss => break :blk .{ .reg = .nds, .lig = true, .simd_prefix = .p_f3, .wig = true },
|
||||
else => unreachable,
|
||||
},
|
||||
.rvmi => switch (tag) {
|
||||
.vcmpsd => break :blk .{ .reg = .nds, .lig = true, .simd_prefix = .p_f2, .wig = true },
|
||||
else => return null,
|
||||
.vcmpss => break :blk .{ .reg = .nds, .lig = true, .simd_prefix = .p_f3, .wig = true },
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
@ -1711,7 +1702,7 @@ inline fn getVexPrefix(tag: Tag, enc: Encoding) ?VexPrefix {
|
||||
.p_f3 => vex.simd_prefix_f3(),
|
||||
}
|
||||
|
||||
return VexPrefix{ .prefix = vex, .reg = switch (desc.reg) {
|
||||
return VexEncoding{ .prefix = vex, .reg = switch (desc.reg) {
|
||||
.none => null,
|
||||
.nds => .nds,
|
||||
.dds => .dds,
|
||||
@ -1862,7 +1853,7 @@ const RegisterOrMemory = union(enum) {
|
||||
|
||||
fn lowerToZoEnc(tag: Tag, code: *std.ArrayList(u8)) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const opc = getOpCode(tag, .zo, false).?;
|
||||
const opc = getOpCode(tag, .zo, false);
|
||||
const encoder = try Encoder.init(code, 2);
|
||||
switch (tag) {
|
||||
.cqo => {
|
||||
@ -1879,12 +1870,12 @@ fn lowerToIEnc(tag: Tag, imm: u32, code: *std.ArrayList(u8)) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
if (tag == .ret_far or tag == .ret_near) {
|
||||
const encoder = try Encoder.init(code, 3);
|
||||
const opc = getOpCode(tag, .i, false).?;
|
||||
const opc = getOpCode(tag, .i, false);
|
||||
opc.encode(encoder);
|
||||
encoder.imm16(@bitCast(i16, @truncate(u16, imm)));
|
||||
return;
|
||||
}
|
||||
const opc = getOpCode(tag, .i, immOpSize(imm) == 8).?;
|
||||
const opc = getOpCode(tag, .i, immOpSize(imm) == 8);
|
||||
const encoder = try Encoder.init(code, 5);
|
||||
if (immOpSize(imm) == 16) {
|
||||
encoder.prefix16BitMode();
|
||||
@ -1895,7 +1886,7 @@ fn lowerToIEnc(tag: Tag, imm: u32, code: *std.ArrayList(u8)) InnerError!void {
|
||||
|
||||
fn lowerToOEnc(tag: Tag, reg: Register, code: *std.ArrayList(u8)) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const opc = getOpCode(tag, .o, false).?;
|
||||
const opc = getOpCode(tag, .o, false);
|
||||
const encoder = try Encoder.init(code, 3);
|
||||
if (reg.size() == 16) {
|
||||
encoder.prefix16BitMode();
|
||||
@ -1909,7 +1900,7 @@ fn lowerToOEnc(tag: Tag, reg: Register, code: *std.ArrayList(u8)) InnerError!voi
|
||||
|
||||
fn lowerToDEnc(tag: Tag, imm: u32, code: *std.ArrayList(u8)) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const opc = getOpCode(tag, .d, false).?;
|
||||
const opc = getOpCode(tag, .d, false);
|
||||
const encoder = try Encoder.init(code, 6);
|
||||
opc.encode(encoder);
|
||||
encoder.imm32(@bitCast(i32, imm));
|
||||
@ -1917,8 +1908,8 @@ fn lowerToDEnc(tag: Tag, imm: u32, code: *std.ArrayList(u8)) InnerError!void {
|
||||
|
||||
fn lowerToMxEnc(tag: Tag, reg_or_mem: RegisterOrMemory, enc: Encoding, code: *std.ArrayList(u8)) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const opc = getOpCode(tag, enc, reg_or_mem.size() == 8).?;
|
||||
const modrm_ext = getModRmExt(tag).?;
|
||||
const opc = getOpCode(tag, enc, reg_or_mem.size() == 8);
|
||||
const modrm_ext = getModRmExt(tag);
|
||||
switch (reg_or_mem) {
|
||||
.register => |reg| {
|
||||
const encoder = try Encoder.init(code, 4);
|
||||
@ -1973,10 +1964,7 @@ fn lowerToFdEnc(tag: Tag, reg: Register, moffs: u64, code: *std.ArrayList(u8)) I
|
||||
|
||||
fn lowerToTdFdEnc(tag: Tag, reg: Register, moffs: u64, code: *std.ArrayList(u8), td: bool) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const opc = if (td)
|
||||
getOpCode(tag, .td, reg.size() == 8).?
|
||||
else
|
||||
getOpCode(tag, .fd, reg.size() == 8).?;
|
||||
const opc = if (td) getOpCode(tag, .td, reg.size() == 8) else getOpCode(tag, .fd, reg.size() == 8);
|
||||
const encoder = try Encoder.init(code, 10);
|
||||
if (reg.size() == 16) {
|
||||
encoder.prefix16BitMode();
|
||||
@ -1996,7 +1984,7 @@ fn lowerToTdFdEnc(tag: Tag, reg: Register, moffs: u64, code: *std.ArrayList(u8),
|
||||
|
||||
fn lowerToOiEnc(tag: Tag, reg: Register, imm: u64, code: *std.ArrayList(u8)) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const opc = getOpCode(tag, .oi, reg.size() == 8).?;
|
||||
const opc = getOpCode(tag, .oi, reg.size() == 8);
|
||||
const encoder = try Encoder.init(code, 10);
|
||||
if (reg.size() == 16) {
|
||||
encoder.prefix16BitMode();
|
||||
@ -2023,8 +2011,8 @@ fn lowerToMiXEnc(
|
||||
code: *std.ArrayList(u8),
|
||||
) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const modrm_ext = getModRmExt(tag).?;
|
||||
const opc = getOpCode(tag, enc, reg_or_mem.size() == 8).?;
|
||||
const modrm_ext = getModRmExt(tag);
|
||||
const opc = getOpCode(tag, enc, reg_or_mem.size() == 8);
|
||||
switch (reg_or_mem) {
|
||||
.register => |dst_reg| {
|
||||
const encoder = try Encoder.init(code, 7);
|
||||
@ -2079,7 +2067,7 @@ fn lowerToRmEnc(
|
||||
code: *std.ArrayList(u8),
|
||||
) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const opc = getOpCode(tag, .rm, reg.size() == 8 or reg_or_mem.size() == 8).?;
|
||||
const opc = getOpCode(tag, .rm, reg.size() == 8 or reg_or_mem.size() == 8);
|
||||
switch (reg_or_mem) {
|
||||
.register => |src_reg| {
|
||||
const encoder = try Encoder.init(code, 5);
|
||||
@ -2126,7 +2114,7 @@ fn lowerToMrEnc(
|
||||
code: *std.ArrayList(u8),
|
||||
) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const opc = getOpCode(tag, .mr, reg.size() == 8 or reg_or_mem.size() == 8).?;
|
||||
const opc = getOpCode(tag, .mr, reg.size() == 8 or reg_or_mem.size() == 8);
|
||||
switch (reg_or_mem) {
|
||||
.register => |dst_reg| {
|
||||
const encoder = try Encoder.init(code, 4);
|
||||
@ -2172,7 +2160,7 @@ fn lowerToRmiEnc(
|
||||
code: *std.ArrayList(u8),
|
||||
) InnerError!void {
|
||||
assert(!tag.isAvx());
|
||||
const opc = getOpCode(tag, .rmi, false).?;
|
||||
const opc = getOpCode(tag, .rmi, false);
|
||||
const encoder = try Encoder.init(code, 13);
|
||||
if (reg.size() == 16) {
|
||||
encoder.prefix16BitMode();
|
||||
@ -2216,9 +2204,9 @@ fn lowerToVmEnc(
|
||||
reg_or_mem: RegisterOrMemory,
|
||||
code: *std.ArrayList(u8),
|
||||
) InnerError!void {
|
||||
const opc = getOpCode(tag, .vm, false).?;
|
||||
var vex_prefix = getVexPrefix(tag, .vm).?;
|
||||
const vex = &vex_prefix.prefix;
|
||||
const opc = getOpCode(tag, .vm, false);
|
||||
var enc = getVexEncoding(tag, .vm);
|
||||
const vex = &enc.prefix;
|
||||
switch (reg_or_mem) {
|
||||
.register => |src_reg| {
|
||||
const encoder = try Encoder.init(code, 5);
|
||||
@ -2226,12 +2214,11 @@ fn lowerToVmEnc(
|
||||
.r = reg.isExtended(),
|
||||
.b = src_reg.isExtended(),
|
||||
});
|
||||
encoder.vex(vex_prefix.prefix);
|
||||
encoder.vex(enc.prefix);
|
||||
opc.encode(encoder);
|
||||
encoder.modRm_direct(reg.lowEnc(), src_reg.lowEnc());
|
||||
},
|
||||
.memory => |src_mem| {
|
||||
assert(src_mem.ptr_size == .qword_ptr);
|
||||
const encoder = try Encoder.init(code, 10);
|
||||
if (src_mem.base) |base| {
|
||||
vex.rex(.{
|
||||
@ -2243,7 +2230,7 @@ fn lowerToVmEnc(
|
||||
.r = reg.isExtended(),
|
||||
});
|
||||
}
|
||||
encoder.vex(vex_prefix.prefix);
|
||||
encoder.vex(enc.prefix);
|
||||
opc.encode(encoder);
|
||||
src_mem.encode(encoder, reg.lowEnc());
|
||||
},
|
||||
@ -2257,9 +2244,9 @@ fn lowerToMvEnc(
|
||||
reg: Register,
|
||||
code: *std.ArrayList(u8),
|
||||
) InnerError!void {
|
||||
const opc = getOpCode(tag, .mv, false).?;
|
||||
var vex_prefix = getVexPrefix(tag, .mv).?;
|
||||
const vex = &vex_prefix.prefix;
|
||||
const opc = getOpCode(tag, .mv, false);
|
||||
var enc = getVexEncoding(tag, .mv);
|
||||
const vex = &enc.prefix;
|
||||
switch (reg_or_mem) {
|
||||
.register => |dst_reg| {
|
||||
const encoder = try Encoder.init(code, 4);
|
||||
@ -2267,12 +2254,11 @@ fn lowerToMvEnc(
|
||||
.r = reg.isExtended(),
|
||||
.b = dst_reg.isExtended(),
|
||||
});
|
||||
encoder.vex(vex_prefix.prefix);
|
||||
encoder.vex(enc.prefix);
|
||||
opc.encode(encoder);
|
||||
encoder.modRm_direct(reg.lowEnc(), dst_reg.lowEnc());
|
||||
},
|
||||
.memory => |dst_mem| {
|
||||
assert(dst_mem.ptr_size == .qword_ptr);
|
||||
const encoder = try Encoder.init(code, 10);
|
||||
if (dst_mem.base) |base| {
|
||||
vex.rex(.{
|
||||
@ -2284,7 +2270,7 @@ fn lowerToMvEnc(
|
||||
.r = reg.isExtended(),
|
||||
});
|
||||
}
|
||||
encoder.vex(vex_prefix.prefix);
|
||||
encoder.vex(enc.prefix);
|
||||
opc.encode(encoder);
|
||||
dst_mem.encode(encoder, reg.lowEnc());
|
||||
},
|
||||
@ -2298,12 +2284,12 @@ fn lowerToRvmEnc(
|
||||
reg_or_mem: RegisterOrMemory,
|
||||
code: *std.ArrayList(u8),
|
||||
) InnerError!void {
|
||||
const opc = getOpCode(tag, .rvm, false).?;
|
||||
var vex_prefix = getVexPrefix(tag, .rvm).?;
|
||||
const vex = &vex_prefix.prefix;
|
||||
const opc = getOpCode(tag, .rvm, false);
|
||||
var enc = getVexEncoding(tag, .rvm);
|
||||
const vex = &enc.prefix;
|
||||
switch (reg_or_mem) {
|
||||
.register => |reg3| {
|
||||
if (vex_prefix.reg) |vvvv| {
|
||||
if (enc.reg) |vvvv| {
|
||||
switch (vvvv) {
|
||||
.nds => vex.reg(reg2.enc()),
|
||||
else => unreachable, // TODO
|
||||
@ -2314,7 +2300,7 @@ fn lowerToRvmEnc(
|
||||
.r = reg1.isExtended(),
|
||||
.b = reg3.isExtended(),
|
||||
});
|
||||
encoder.vex(vex_prefix.prefix);
|
||||
encoder.vex(enc.prefix);
|
||||
opc.encode(encoder);
|
||||
encoder.modRm_direct(reg1.lowEnc(), reg3.lowEnc());
|
||||
},
|
||||
@ -2333,13 +2319,13 @@ fn lowerToRvmiEnc(
|
||||
imm: u32,
|
||||
code: *std.ArrayList(u8),
|
||||
) InnerError!void {
|
||||
const opc = getOpCode(tag, .rvmi, false).?;
|
||||
var vex_prefix = getVexPrefix(tag, .rvmi).?;
|
||||
const vex = &vex_prefix.prefix;
|
||||
const opc = getOpCode(tag, .rvmi, false);
|
||||
var enc = getVexEncoding(tag, .rvmi);
|
||||
const vex = &enc.prefix;
|
||||
const encoder: Encoder = blk: {
|
||||
switch (reg_or_mem) {
|
||||
.register => |reg3| {
|
||||
if (vex_prefix.reg) |vvvv| {
|
||||
if (enc.reg) |vvvv| {
|
||||
switch (vvvv) {
|
||||
.nds => vex.reg(reg2.enc()),
|
||||
else => unreachable, // TODO
|
||||
@ -2350,7 +2336,7 @@ fn lowerToRvmiEnc(
|
||||
.r = reg1.isExtended(),
|
||||
.b = reg3.isExtended(),
|
||||
});
|
||||
encoder.vex(vex_prefix.prefix);
|
||||
encoder.vex(enc.prefix);
|
||||
opc.encode(encoder);
|
||||
encoder.modRm_direct(reg1.lowEnc(), reg3.lowEnc());
|
||||
break :blk encoder;
|
||||
|
||||
@ -351,14 +351,17 @@ pub const Inst = struct {
|
||||
/// 0b01 qword ptr [reg1 + imm32], reg2
|
||||
/// 0b10 reg1, reg2
|
||||
mov_f64,
|
||||
mov_f32,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg1, reg2
|
||||
add_f64,
|
||||
add_f32,
|
||||
|
||||
/// ops flags: form:
|
||||
///
|
||||
cmp_f64,
|
||||
cmp_f32,
|
||||
|
||||
/// Pseudo-instructions
|
||||
/// call extern function
|
||||
|
||||
@ -1,163 +1,163 @@
|
||||
const builtin = @import("builtin");
|
||||
|
||||
test {
|
||||
_ = @import("behavior/align.zig");
|
||||
_ = @import("behavior/alignof.zig");
|
||||
_ = @import("behavior/array.zig");
|
||||
_ = @import("behavior/async_fn.zig");
|
||||
_ = @import("behavior/atomics.zig");
|
||||
_ = @import("behavior/await_struct.zig");
|
||||
// _ = @import("behavior/align.zig");
|
||||
// _ = @import("behavior/alignof.zig");
|
||||
// _ = @import("behavior/array.zig");
|
||||
// _ = @import("behavior/async_fn.zig");
|
||||
// _ = @import("behavior/atomics.zig");
|
||||
// _ = @import("behavior/await_struct.zig");
|
||||
_ = @import("behavior/basic.zig");
|
||||
_ = @import("behavior/bit_shifting.zig");
|
||||
_ = @import("behavior/bitcast.zig");
|
||||
_ = @import("behavior/bitreverse.zig");
|
||||
_ = @import("behavior/bool.zig");
|
||||
_ = @import("behavior/bugs/394.zig");
|
||||
_ = @import("behavior/bugs/421.zig");
|
||||
_ = @import("behavior/bugs/529.zig");
|
||||
_ = @import("behavior/bugs/624.zig");
|
||||
_ = @import("behavior/bugs/655.zig");
|
||||
_ = @import("behavior/bugs/656.zig");
|
||||
_ = @import("behavior/bugs/679.zig");
|
||||
_ = @import("behavior/bugs/704.zig");
|
||||
_ = @import("behavior/bugs/718.zig");
|
||||
_ = @import("behavior/bugs/726.zig");
|
||||
_ = @import("behavior/bugs/828.zig");
|
||||
_ = @import("behavior/bugs/920.zig");
|
||||
_ = @import("behavior/bugs/1025.zig");
|
||||
_ = @import("behavior/bugs/1076.zig");
|
||||
_ = @import("behavior/bugs/1111.zig");
|
||||
_ = @import("behavior/bugs/1120.zig");
|
||||
_ = @import("behavior/bugs/1277.zig");
|
||||
_ = @import("behavior/bugs/1310.zig");
|
||||
_ = @import("behavior/bugs/1381.zig");
|
||||
_ = @import("behavior/bugs/1421.zig");
|
||||
_ = @import("behavior/bugs/1442.zig");
|
||||
_ = @import("behavior/bugs/1486.zig");
|
||||
_ = @import("behavior/bugs/1500.zig");
|
||||
_ = @import("behavior/bugs/1607.zig");
|
||||
_ = @import("behavior/bugs/1735.zig");
|
||||
_ = @import("behavior/bugs/1741.zig");
|
||||
_ = @import("behavior/bugs/1851.zig");
|
||||
_ = @import("behavior/bugs/1914.zig");
|
||||
_ = @import("behavior/bugs/2006.zig");
|
||||
_ = @import("behavior/bugs/2114.zig");
|
||||
_ = @import("behavior/bugs/2346.zig");
|
||||
_ = @import("behavior/bugs/2578.zig");
|
||||
_ = @import("behavior/bugs/2692.zig");
|
||||
_ = @import("behavior/bugs/2889.zig");
|
||||
_ = @import("behavior/bugs/3007.zig");
|
||||
_ = @import("behavior/bugs/3046.zig");
|
||||
_ = @import("behavior/bugs/3112.zig");
|
||||
_ = @import("behavior/bugs/3367.zig");
|
||||
_ = @import("behavior/bugs/3384.zig");
|
||||
_ = @import("behavior/bugs/3586.zig");
|
||||
_ = @import("behavior/bugs/3742.zig");
|
||||
_ = @import("behavior/bugs/3779.zig");
|
||||
_ = @import("behavior/bugs/4328.zig");
|
||||
_ = @import("behavior/bugs/4560.zig");
|
||||
_ = @import("behavior/bugs/4769_a.zig");
|
||||
_ = @import("behavior/bugs/4769_b.zig");
|
||||
_ = @import("behavior/bugs/4954.zig");
|
||||
_ = @import("behavior/bugs/5398.zig");
|
||||
_ = @import("behavior/bugs/5413.zig");
|
||||
_ = @import("behavior/bugs/5474.zig");
|
||||
_ = @import("behavior/bugs/5487.zig");
|
||||
_ = @import("behavior/bugs/6456.zig");
|
||||
_ = @import("behavior/bugs/6781.zig");
|
||||
_ = @import("behavior/bugs/6850.zig");
|
||||
_ = @import("behavior/bugs/7003.zig");
|
||||
_ = @import("behavior/bugs/7027.zig");
|
||||
_ = @import("behavior/bugs/7047.zig");
|
||||
_ = @import("behavior/bugs/7187.zig");
|
||||
_ = @import("behavior/bugs/7250.zig");
|
||||
_ = @import("behavior/bugs/9584.zig");
|
||||
_ = @import("behavior/bugs/10138.zig");
|
||||
_ = @import("behavior/bugs/10147.zig");
|
||||
_ = @import("behavior/bugs/10970.zig");
|
||||
_ = @import("behavior/bugs/11046.zig");
|
||||
_ = @import("behavior/bugs/11100.zig");
|
||||
_ = @import("behavior/bugs/11139.zig");
|
||||
_ = @import("behavior/bugs/11159.zig");
|
||||
_ = @import("behavior/bugs/11162.zig");
|
||||
_ = @import("behavior/bugs/11165.zig");
|
||||
_ = @import("behavior/bugs/11181.zig");
|
||||
_ = @import("behavior/bugs/11182.zig");
|
||||
_ = @import("behavior/bugs/11213.zig");
|
||||
_ = @import("behavior/byteswap.zig");
|
||||
_ = @import("behavior/byval_arg_var.zig");
|
||||
_ = @import("behavior/call.zig");
|
||||
_ = @import("behavior/cast.zig");
|
||||
_ = @import("behavior/cast_int.zig");
|
||||
_ = @import("behavior/comptime_memory.zig");
|
||||
_ = @import("behavior/const_slice_child.zig");
|
||||
_ = @import("behavior/defer.zig");
|
||||
_ = @import("behavior/enum.zig");
|
||||
_ = @import("behavior/error.zig");
|
||||
_ = @import("behavior/eval.zig");
|
||||
_ = @import("behavior/field_parent_ptr.zig");
|
||||
_ = @import("behavior/floatop.zig");
|
||||
_ = @import("behavior/fn.zig");
|
||||
_ = @import("behavior/fn_delegation.zig");
|
||||
_ = @import("behavior/fn_in_struct_in_comptime.zig");
|
||||
_ = @import("behavior/for.zig");
|
||||
_ = @import("behavior/generics.zig");
|
||||
_ = @import("behavior/hasdecl.zig");
|
||||
_ = @import("behavior/hasfield.zig");
|
||||
_ = @import("behavior/if.zig");
|
||||
_ = @import("behavior/import.zig");
|
||||
_ = @import("behavior/incomplete_struct_param_tld.zig");
|
||||
_ = @import("behavior/int128.zig");
|
||||
_ = @import("behavior/int_div.zig");
|
||||
_ = @import("behavior/inttoptr.zig");
|
||||
_ = @import("behavior/ir_block_deps.zig");
|
||||
_ = @import("behavior/math.zig");
|
||||
_ = @import("behavior/maximum_minimum.zig");
|
||||
_ = @import("behavior/member_func.zig");
|
||||
_ = @import("behavior/merge_error_sets.zig");
|
||||
_ = @import("behavior/muladd.zig");
|
||||
_ = @import("behavior/namespace_depends_on_compile_var.zig");
|
||||
_ = @import("behavior/null.zig");
|
||||
_ = @import("behavior/optional.zig");
|
||||
_ = @import("behavior/pointers.zig");
|
||||
_ = @import("behavior/popcount.zig");
|
||||
_ = @import("behavior/prefetch.zig");
|
||||
_ = @import("behavior/ptrcast.zig");
|
||||
_ = @import("behavior/pub_enum.zig");
|
||||
_ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
|
||||
_ = @import("behavior/reflection.zig");
|
||||
_ = @import("behavior/saturating_arithmetic.zig");
|
||||
_ = @import("behavior/select.zig");
|
||||
_ = @import("behavior/shuffle.zig");
|
||||
_ = @import("behavior/sizeof_and_typeof.zig");
|
||||
_ = @import("behavior/slice.zig");
|
||||
_ = @import("behavior/slice_sentinel_comptime.zig");
|
||||
_ = @import("behavior/src.zig");
|
||||
_ = @import("behavior/struct.zig");
|
||||
_ = @import("behavior/packed-struct.zig");
|
||||
_ = @import("behavior/struct_contains_null_ptr_itself.zig");
|
||||
_ = @import("behavior/struct_contains_slice_of_itself.zig");
|
||||
_ = @import("behavior/switch.zig");
|
||||
_ = @import("behavior/switch_prong_err_enum.zig");
|
||||
_ = @import("behavior/switch_prong_implicit_cast.zig");
|
||||
_ = @import("behavior/this.zig");
|
||||
_ = @import("behavior/translate_c_macros.zig");
|
||||
_ = @import("behavior/truncate.zig");
|
||||
_ = @import("behavior/try.zig");
|
||||
_ = @import("behavior/tuple.zig");
|
||||
_ = @import("behavior/type.zig");
|
||||
_ = @import("behavior/type_info.zig");
|
||||
_ = @import("behavior/typename.zig");
|
||||
_ = @import("behavior/undefined.zig");
|
||||
_ = @import("behavior/underscore.zig");
|
||||
_ = @import("behavior/union.zig");
|
||||
_ = @import("behavior/union_with_members.zig");
|
||||
_ = @import("behavior/usingnamespace.zig");
|
||||
_ = @import("behavior/var_args.zig");
|
||||
_ = @import("behavior/vector.zig");
|
||||
_ = @import("behavior/void.zig");
|
||||
_ = @import("behavior/while.zig");
|
||||
_ = @import("behavior/widening.zig");
|
||||
// _ = @import("behavior/bit_shifting.zig");
|
||||
// _ = @import("behavior/bitcast.zig");
|
||||
// _ = @import("behavior/bitreverse.zig");
|
||||
// _ = @import("behavior/bool.zig");
|
||||
// _ = @import("behavior/bugs/394.zig");
|
||||
// _ = @import("behavior/bugs/421.zig");
|
||||
// _ = @import("behavior/bugs/529.zig");
|
||||
// _ = @import("behavior/bugs/624.zig");
|
||||
// _ = @import("behavior/bugs/655.zig");
|
||||
// _ = @import("behavior/bugs/656.zig");
|
||||
// _ = @import("behavior/bugs/679.zig");
|
||||
// _ = @import("behavior/bugs/704.zig");
|
||||
// _ = @import("behavior/bugs/718.zig");
|
||||
// _ = @import("behavior/bugs/726.zig");
|
||||
// _ = @import("behavior/bugs/828.zig");
|
||||
// _ = @import("behavior/bugs/920.zig");
|
||||
// _ = @import("behavior/bugs/1025.zig");
|
||||
// _ = @import("behavior/bugs/1076.zig");
|
||||
// _ = @import("behavior/bugs/1111.zig");
|
||||
// _ = @import("behavior/bugs/1120.zig");
|
||||
// _ = @import("behavior/bugs/1277.zig");
|
||||
// _ = @import("behavior/bugs/1310.zig");
|
||||
// _ = @import("behavior/bugs/1381.zig");
|
||||
// _ = @import("behavior/bugs/1421.zig");
|
||||
// _ = @import("behavior/bugs/1442.zig");
|
||||
// _ = @import("behavior/bugs/1486.zig");
|
||||
// _ = @import("behavior/bugs/1500.zig");
|
||||
// _ = @import("behavior/bugs/1607.zig");
|
||||
// _ = @import("behavior/bugs/1735.zig");
|
||||
// _ = @import("behavior/bugs/1741.zig");
|
||||
// _ = @import("behavior/bugs/1851.zig");
|
||||
// _ = @import("behavior/bugs/1914.zig");
|
||||
// _ = @import("behavior/bugs/2006.zig");
|
||||
// _ = @import("behavior/bugs/2114.zig");
|
||||
// _ = @import("behavior/bugs/2346.zig");
|
||||
// _ = @import("behavior/bugs/2578.zig");
|
||||
// _ = @import("behavior/bugs/2692.zig");
|
||||
// _ = @import("behavior/bugs/2889.zig");
|
||||
// _ = @import("behavior/bugs/3007.zig");
|
||||
// _ = @import("behavior/bugs/3046.zig");
|
||||
// _ = @import("behavior/bugs/3112.zig");
|
||||
// _ = @import("behavior/bugs/3367.zig");
|
||||
// _ = @import("behavior/bugs/3384.zig");
|
||||
// _ = @import("behavior/bugs/3586.zig");
|
||||
// _ = @import("behavior/bugs/3742.zig");
|
||||
// _ = @import("behavior/bugs/3779.zig");
|
||||
// _ = @import("behavior/bugs/4328.zig");
|
||||
// _ = @import("behavior/bugs/4560.zig");
|
||||
// _ = @import("behavior/bugs/4769_a.zig");
|
||||
// _ = @import("behavior/bugs/4769_b.zig");
|
||||
// _ = @import("behavior/bugs/4954.zig");
|
||||
// _ = @import("behavior/bugs/5398.zig");
|
||||
// _ = @import("behavior/bugs/5413.zig");
|
||||
// _ = @import("behavior/bugs/5474.zig");
|
||||
// _ = @import("behavior/bugs/5487.zig");
|
||||
// _ = @import("behavior/bugs/6456.zig");
|
||||
// _ = @import("behavior/bugs/6781.zig");
|
||||
// _ = @import("behavior/bugs/6850.zig");
|
||||
// _ = @import("behavior/bugs/7003.zig");
|
||||
// _ = @import("behavior/bugs/7027.zig");
|
||||
// _ = @import("behavior/bugs/7047.zig");
|
||||
// _ = @import("behavior/bugs/7187.zig");
|
||||
// _ = @import("behavior/bugs/7250.zig");
|
||||
// _ = @import("behavior/bugs/9584.zig");
|
||||
// _ = @import("behavior/bugs/10138.zig");
|
||||
// _ = @import("behavior/bugs/10147.zig");
|
||||
// _ = @import("behavior/bugs/10970.zig");
|
||||
// _ = @import("behavior/bugs/11046.zig");
|
||||
// _ = @import("behavior/bugs/11100.zig");
|
||||
// _ = @import("behavior/bugs/11139.zig");
|
||||
// _ = @import("behavior/bugs/11159.zig");
|
||||
// _ = @import("behavior/bugs/11162.zig");
|
||||
// _ = @import("behavior/bugs/11165.zig");
|
||||
// _ = @import("behavior/bugs/11181.zig");
|
||||
// _ = @import("behavior/bugs/11182.zig");
|
||||
// _ = @import("behavior/bugs/11213.zig");
|
||||
// _ = @import("behavior/byteswap.zig");
|
||||
// _ = @import("behavior/byval_arg_var.zig");
|
||||
// _ = @import("behavior/call.zig");
|
||||
// _ = @import("behavior/cast.zig");
|
||||
// _ = @import("behavior/cast_int.zig");
|
||||
// _ = @import("behavior/comptime_memory.zig");
|
||||
// _ = @import("behavior/const_slice_child.zig");
|
||||
// _ = @import("behavior/defer.zig");
|
||||
// _ = @import("behavior/enum.zig");
|
||||
// _ = @import("behavior/error.zig");
|
||||
// _ = @import("behavior/eval.zig");
|
||||
// _ = @import("behavior/field_parent_ptr.zig");
|
||||
// _ = @import("behavior/floatop.zig");
|
||||
// _ = @import("behavior/fn.zig");
|
||||
// _ = @import("behavior/fn_delegation.zig");
|
||||
// _ = @import("behavior/fn_in_struct_in_comptime.zig");
|
||||
// _ = @import("behavior/for.zig");
|
||||
// _ = @import("behavior/generics.zig");
|
||||
// _ = @import("behavior/hasdecl.zig");
|
||||
// _ = @import("behavior/hasfield.zig");
|
||||
// _ = @import("behavior/if.zig");
|
||||
// _ = @import("behavior/import.zig");
|
||||
// _ = @import("behavior/incomplete_struct_param_tld.zig");
|
||||
// _ = @import("behavior/int128.zig");
|
||||
// _ = @import("behavior/int_div.zig");
|
||||
// _ = @import("behavior/inttoptr.zig");
|
||||
// _ = @import("behavior/ir_block_deps.zig");
|
||||
// _ = @import("behavior/math.zig");
|
||||
// _ = @import("behavior/maximum_minimum.zig");
|
||||
// _ = @import("behavior/member_func.zig");
|
||||
// _ = @import("behavior/merge_error_sets.zig");
|
||||
// _ = @import("behavior/muladd.zig");
|
||||
// _ = @import("behavior/namespace_depends_on_compile_var.zig");
|
||||
// _ = @import("behavior/null.zig");
|
||||
// _ = @import("behavior/optional.zig");
|
||||
// _ = @import("behavior/pointers.zig");
|
||||
// _ = @import("behavior/popcount.zig");
|
||||
// _ = @import("behavior/prefetch.zig");
|
||||
// _ = @import("behavior/ptrcast.zig");
|
||||
// _ = @import("behavior/pub_enum.zig");
|
||||
// _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
|
||||
// _ = @import("behavior/reflection.zig");
|
||||
// _ = @import("behavior/saturating_arithmetic.zig");
|
||||
// _ = @import("behavior/select.zig");
|
||||
// _ = @import("behavior/shuffle.zig");
|
||||
// _ = @import("behavior/sizeof_and_typeof.zig");
|
||||
// _ = @import("behavior/slice.zig");
|
||||
// _ = @import("behavior/slice_sentinel_comptime.zig");
|
||||
// _ = @import("behavior/src.zig");
|
||||
// _ = @import("behavior/struct.zig");
|
||||
// _ = @import("behavior/packed-struct.zig");
|
||||
// _ = @import("behavior/struct_contains_null_ptr_itself.zig");
|
||||
// _ = @import("behavior/struct_contains_slice_of_itself.zig");
|
||||
// _ = @import("behavior/switch.zig");
|
||||
// _ = @import("behavior/switch_prong_err_enum.zig");
|
||||
// _ = @import("behavior/switch_prong_implicit_cast.zig");
|
||||
// _ = @import("behavior/this.zig");
|
||||
// _ = @import("behavior/translate_c_macros.zig");
|
||||
// _ = @import("behavior/truncate.zig");
|
||||
// _ = @import("behavior/try.zig");
|
||||
// _ = @import("behavior/tuple.zig");
|
||||
// _ = @import("behavior/type.zig");
|
||||
// _ = @import("behavior/type_info.zig");
|
||||
// _ = @import("behavior/typename.zig");
|
||||
// _ = @import("behavior/undefined.zig");
|
||||
// _ = @import("behavior/underscore.zig");
|
||||
// _ = @import("behavior/union.zig");
|
||||
// _ = @import("behavior/union_with_members.zig");
|
||||
// _ = @import("behavior/usingnamespace.zig");
|
||||
// _ = @import("behavior/var_args.zig");
|
||||
// _ = @import("behavior/vector.zig");
|
||||
// _ = @import("behavior/void.zig");
|
||||
// _ = @import("behavior/while.zig");
|
||||
// _ = @import("behavior/widening.zig");
|
||||
|
||||
if (builtin.stage2_arch == .wasm32) {
|
||||
_ = @import("behavior/wasm.zig");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user