diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-07-13 19:15:19 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-13 19:15:19 -0400 |
| commit | 1653a9b2597c66cbcc88ea75d8a4b88c163584a5 (patch) | |
| tree | 9cbe5d66e5088006ac4b5d5b4861a3b8b25a7a54 /src/codegen/llvm.zig | |
| parent | fad95741db7529bbad873fb330c25d64ac765340 (diff) | |
| parent | 92bc3cbe27792be0300fb5f104c011a11f3cf40f (diff) | |
| download | zig-1653a9b2597c66cbcc88ea75d8a4b88c163584a5.tar.gz zig-1653a9b2597c66cbcc88ea75d8a4b88c163584a5.zip | |
Merge pull request #12098 from ziglang/llvm-riscv64
LLVM: implement signext/zeroext attributes
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 8857c96bc1..fe35620d38 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -717,6 +717,11 @@ pub const Object = struct { const ret_ptr = if (sret) llvm_func.getParam(0) else null; const gpa = dg.gpa; + if (ccAbiPromoteInt(fn_info.cc, target, fn_info.return_type)) |s| switch (s) { + .signed => dg.addAttr(llvm_func, 0, "signext"), + .unsigned => dg.addAttr(llvm_func, 0, "zeroext"), + }; + const err_return_tracing = fn_info.return_type.isError() and dg.module.comp.bin_file.options.error_return_tracing; @@ -774,7 +779,10 @@ pub const Object = struct { ); dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align); } - } + } else if (ccAbiPromoteInt(fn_info.cc, target, param_ty)) |s| switch (s) { + .signed => dg.addArgAttr(llvm_func, llvm_arg_i, "signext"), + .unsigned => dg.addArgAttr(llvm_func, llvm_arg_i, "zeroext"), + }; } llvm_arg_i += 1; }, @@ -887,6 +895,13 @@ pub const Object = struct { }; try args.append(loaded); }, + .as_u16 => { + const param = llvm_func.getParam(llvm_arg_i); + llvm_arg_i += 1; + const casted = builder.buildBitCast(param, dg.context.halfType(), ""); + try args.ensureUnusedCapacity(1); + args.appendAssumeCapacity(casted); + }, }; } @@ -2794,6 +2809,9 @@ pub const DeclGen = struct { llvm_params.appendAssumeCapacity(big_int_ty); } }, + .as_u16 => { + try llvm_params.append(dg.context.intType(16)); + }, }; return llvm.functionType( @@ -4234,6 +4252,12 @@ pub const FuncGen = struct { llvm_args.appendAssumeCapacity(load_inst); } }, + .as_u16 => { + const arg = args[it.zig_index - 1]; + const llvm_arg = try self.resolveInst(arg); + const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), ""); + try llvm_args.append(casted); + }, }; const call = self.builder.buildCall( @@ -8965,6 +8989,7 @@ const ParamTypeIterator = struct { abi_sized_int, multiple_llvm_ints, slice, + as_u16, }; pub fn next(it: *ParamTypeIterator) ?Lowering { @@ -9025,6 +9050,15 @@ const ParamTypeIterator = struct { else => false, }; switch (it.target.cpu.arch) { + .riscv32, .riscv64 => { + it.zig_index += 1; + it.llvm_index += 1; + if (ty.tag() == .f16) { + return .as_u16; + } else { + return .byval; + } + }, .mips, .mipsel => { it.zig_index += 1; it.llvm_index += 1; @@ -9135,6 +9169,35 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp }; } +fn ccAbiPromoteInt( + cc: std.builtin.CallingConvention, + target: std.Target, + ty: Type, +) ?std.builtin.Signedness { + switch (cc) { + .Unspecified, .Inline, .Async => return null, + else => {}, + } + const int_info = switch (ty.zigTypeTag()) { + .Int, .Enum, .ErrorSet => ty.intInfo(target), + else => return null, + }; + if (int_info.bits <= 16) return int_info.signedness; + switch (target.cpu.arch) { + .sparc64, + .riscv64, + .powerpc64, + .powerpc64le, + => { + if (int_info.bits < 64) { + return int_info.signedness; + } + }, + else => {}, + } + return null; +} + fn isByRef(ty: Type) bool { // For tuples and structs, if there are more than this many non-void // fields, then we make it byref, otherwise byval. |
