mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 06:15:21 +00:00
stage2: fix some inline asm incompatibilities with stage1
This commit is contained in:
parent
ffa700ee58
commit
13f02c30e6
@ -11406,6 +11406,7 @@ fn zirAsm(
|
||||
// Indicate the output is the asm instruction return value.
|
||||
arg.* = .none;
|
||||
const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);
|
||||
try sema.queueFullTypeResolution(out_ty);
|
||||
expr_ty = try sema.addType(out_ty);
|
||||
} else {
|
||||
arg.* = try sema.resolveInst(output.data.operand);
|
||||
@ -11430,7 +11431,10 @@ fn zirAsm(
|
||||
switch (uncasted_arg_ty.zigTypeTag()) {
|
||||
.ComptimeInt => arg.* = try sema.coerce(block, Type.initTag(.usize), uncasted_arg, src),
|
||||
.ComptimeFloat => arg.* = try sema.coerce(block, Type.initTag(.f64), uncasted_arg, src),
|
||||
else => arg.* = uncasted_arg,
|
||||
else => {
|
||||
arg.* = uncasted_arg;
|
||||
try sema.queueFullTypeResolution(uncasted_arg_ty);
|
||||
},
|
||||
}
|
||||
|
||||
const constraint = sema.code.nullTerminatedString(input.data.constraint);
|
||||
|
||||
@ -5421,6 +5421,8 @@ pub const FuncGen = struct {
|
||||
const llvm_params_len = inputs.len + outputs.len - return_count;
|
||||
const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len);
|
||||
const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len);
|
||||
const target = self.dg.module.getTarget();
|
||||
|
||||
var llvm_param_i: usize = 0;
|
||||
var total_i: usize = 0;
|
||||
|
||||
@ -5449,7 +5451,18 @@ pub const FuncGen = struct {
|
||||
llvm_param_types[llvm_param_i] = output_inst.typeOf();
|
||||
llvm_param_i += 1;
|
||||
}
|
||||
llvm_constraints.appendSliceAssumeCapacity(constraint[1..]);
|
||||
|
||||
// LLVM uses commas internally to separate different constraints,
|
||||
// alternative constraints are achieved with pipes.
|
||||
// We still allow the user to use commas in a way that is similar
|
||||
// to GCC's inline assembly.
|
||||
// http://llvm.org/docs/LangRef.html#constraint-codes
|
||||
for (constraint[1..]) |byte| {
|
||||
llvm_constraints.appendAssumeCapacity(switch (byte) {
|
||||
',' => '|',
|
||||
else => byte,
|
||||
});
|
||||
}
|
||||
|
||||
name_map.putAssumeCapacityNoClobber(name, {});
|
||||
total_i += 1;
|
||||
@ -5464,15 +5477,43 @@ pub const FuncGen = struct {
|
||||
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
||||
|
||||
const arg_llvm_value = try self.resolveInst(input);
|
||||
|
||||
llvm_param_values[llvm_param_i] = arg_llvm_value;
|
||||
llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
|
||||
const arg_ty = self.air.typeOf(input);
|
||||
if (isByRef(arg_ty)) {
|
||||
if (constraintAllowsMemory(constraint)) {
|
||||
llvm_param_values[llvm_param_i] = arg_llvm_value;
|
||||
llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
|
||||
} else {
|
||||
const alignment = arg_ty.abiAlignment(target);
|
||||
const load_inst = self.builder.buildLoad(arg_llvm_value, "");
|
||||
load_inst.setAlignment(alignment);
|
||||
llvm_param_values[llvm_param_i] = load_inst;
|
||||
llvm_param_types[llvm_param_i] = load_inst.typeOf();
|
||||
}
|
||||
} else {
|
||||
if (constraintAllowsRegister(constraint)) {
|
||||
llvm_param_values[llvm_param_i] = arg_llvm_value;
|
||||
llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
|
||||
} else {
|
||||
const alignment = arg_ty.abiAlignment(target);
|
||||
const arg_ptr = self.buildAlloca(arg_llvm_value.typeOf());
|
||||
arg_ptr.setAlignment(alignment);
|
||||
const store_inst = self.builder.buildStore(arg_llvm_value, arg_ptr);
|
||||
store_inst.setAlignment(alignment);
|
||||
llvm_param_values[llvm_param_i] = arg_ptr;
|
||||
llvm_param_types[llvm_param_i] = arg_ptr.typeOf();
|
||||
}
|
||||
}
|
||||
|
||||
try llvm_constraints.ensureUnusedCapacity(self.gpa, constraint.len + 1);
|
||||
if (total_i != 0) {
|
||||
llvm_constraints.appendAssumeCapacity(',');
|
||||
}
|
||||
llvm_constraints.appendSliceAssumeCapacity(constraint);
|
||||
for (constraint) |byte| {
|
||||
llvm_constraints.appendAssumeCapacity(switch (byte) {
|
||||
',' => '|',
|
||||
else => byte,
|
||||
});
|
||||
}
|
||||
|
||||
if (!std.mem.eql(u8, name, "_")) {
|
||||
name_map.putAssumeCapacityNoClobber(name, {});
|
||||
@ -9307,3 +9348,11 @@ fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u1 {
|
||||
fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u1 {
|
||||
return @boolToInt(Type.anyerror.abiAlignment(target) <= payload_ty.abiAlignment(target));
|
||||
}
|
||||
|
||||
fn constraintAllowsMemory(constraint: []const u8) bool {
|
||||
return constraint[0] == 'm';
|
||||
}
|
||||
|
||||
fn constraintAllowsRegister(constraint: []const u8) bool {
|
||||
return constraint[0] != 'm';
|
||||
}
|
||||
|
||||
@ -35,7 +35,6 @@ test "output constraint modifiers" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
|
||||
// This is only testing compilation.
|
||||
var a: u32 = 3;
|
||||
@ -57,7 +56,6 @@ test "alternative constraints" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
|
||||
// Make sure we allow commas as a separator for alternative constraints.
|
||||
var a: u32 = 3;
|
||||
@ -122,7 +120,6 @@ test "struct/array/union types as input values" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
|
||||
asm volatile (""
|
||||
:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user