authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-15 19:05:36-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-16 10:27:40-07:00
log5aa50bcbff7f6bee7217f5e6e3e358f47aa748c8
tree2d907048e847db6087690bd3807e56f8c9291b56
parent8a19eeb8af18ebb929cfda5efa3149d88620c1c7

fix mips clobbers


2 files changed, 275 insertions(+), 21 deletions(-)

lib/std/builtin/assembly.zig+11
......@@ -1004,6 +1004,8 @@ pub const Clobbers = switch (@import("builtin").cpu.arch) {
10041004 /// addresses other than those derived from input pointer provenance.
10051005 memory: bool = false,
10061006
1007 xcc: bool = false,
1008
10071009 psr: bool = false,
10081010 ccr: bool = false,
10091011 gsr: bool = false,
......@@ -2179,6 +2181,15 @@ pub const Clobbers = switch (@import("builtin").cpu.arch) {
21792181 p0: bool = false,
21802182 p1: bool = false,
21812183 p2: bool = false,
2184
2185 msa_ir: bool = false,
2186 msa_csr: bool = false,
2187 msa_access: bool = false,
2188 msa_save: bool = false,
2189 msa_modify: bool = false,
2190 msa_request: bool = false,
2191 msa_map: bool = false,
2192 msa_unmap: bool = false,
21822193 },
21832194 else => packed struct {
21842195 /// Whether the inline assembly code may perform stores to memory
src/codegen/llvm.zig+264-21
......@@ -7277,7 +7277,7 @@ pub const FuncGen = struct {
72777277
72787278 var llvm_ret_i: usize = 0;
72797279 var llvm_param_i: usize = 0;
7280 var total_i: u16 = 0;
7280 var total_i: usize = 0;
72817281
72827282 var name_map: std.StringArrayHashMapUnmanaged(u16) = .empty;
72837283 try name_map.ensureUnusedCapacity(arena, max_param_count);
......@@ -7359,7 +7359,7 @@ pub const FuncGen = struct {
73597359 if (!std.mem.eql(u8, name, "_")) {
73607360 const gop = name_map.getOrPutAssumeCapacity(name);
73617361 if (gop.found_existing) return self.todo("duplicate asm output name '{s}'", .{name});
7362 gop.value_ptr.* = total_i;
7362 gop.value_ptr.* = @intCast(total_i);
73637363 }
73647364 total_i += 1;
73657365 }
......@@ -7414,7 +7414,7 @@ pub const FuncGen = struct {
74147414 if (!std.mem.eql(u8, name, "_")) {
74157415 const gop = name_map.getOrPutAssumeCapacity(name);
74167416 if (gop.found_existing) return self.todo("duplicate asm input name '{s}'", .{name});
7417 gop.value_ptr.* = total_i;
7417 gop.value_ptr.* = @intCast(total_i);
74187418 }
74197419
74207420 // In the case of indirect inputs, LLVM requires the callsite to have
......@@ -7470,18 +7470,13 @@ pub const FuncGen = struct {
74707470 const ip = &zcu.intern_pool;
74717471 const aggregate = ip.indexToKey(extra.data.clobbers).aggregate;
74727472 const struct_type: Type = .fromInterned(aggregate.ty);
7473 if (total_i != 0) try llvm_constraints.append(gpa, ',');
74737474 switch (aggregate.storage) {
74747475 .elems => |elems| for (elems, 0..) |elem, i| {
74757476 switch (elem) {
74767477 .bool_true => {
74777478 const name = struct_type.structFieldName(i, zcu).toSlice(ip).?;
7478 try llvm_constraints.ensureUnusedCapacity(gpa, name.len + 4);
7479 if (total_i != 0) llvm_constraints.appendAssumeCapacity(',');
7480 llvm_constraints.appendSliceAssumeCapacity("~{");
7481 llvm_constraints.appendSliceAssumeCapacity(name);
7482 llvm_constraints.appendSliceAssumeCapacity("}");
7483
7484 total_i += 1;
7479 total_i += try appendConstraints(gpa, &llvm_constraints, name, target);
74857480 },
74867481 .bool_false => continue,
74877482 else => unreachable,
......@@ -7490,13 +7485,7 @@ pub const FuncGen = struct {
74907485 .repeated_elem => |elem| switch (elem) {
74917486 .bool_true => for (0..struct_type.structFieldCount(zcu)) |i| {
74927487 const name = struct_type.structFieldName(i, zcu).toSlice(ip).?;
7493 try llvm_constraints.ensureUnusedCapacity(gpa, name.len + 4);
7494 if (total_i != 0) llvm_constraints.appendAssumeCapacity(',');
7495 llvm_constraints.appendSliceAssumeCapacity("~{");
7496 llvm_constraints.appendSliceAssumeCapacity(name);
7497 llvm_constraints.appendSliceAssumeCapacity("}");
7498
7499 total_i += 1;
7488 total_i += try appendConstraints(gpa, &llvm_constraints, name, target);
75007489 },
75017490 .bool_false => {},
75027491 else => unreachable,
......@@ -7515,18 +7504,18 @@ pub const FuncGen = struct {
75157504 // to be buggy and regress often.
75167505 switch (target.cpu.arch) {
75177506 .x86_64, .x86 => {
7518 if (total_i != 0) try llvm_constraints.append(gpa, ',');
7519 try llvm_constraints.appendSlice(gpa, "~{dirflag},~{fpsr},~{flags}");
7507 try llvm_constraints.appendSlice(gpa, "~{dirflag},~{fpsr},~{flags},");
75207508 total_i += 3;
75217509 },
75227510 .mips, .mipsel, .mips64, .mips64el => {
7523 if (total_i != 0) try llvm_constraints.append(gpa, ',');
7524 try llvm_constraints.appendSlice(gpa, "~{$1}");
7511 try llvm_constraints.appendSlice(gpa, "~{$1},");
75257512 total_i += 1;
75267513 },
75277514 else => {},
75287515 }
75297516
7517 if (std.mem.endsWith(u8, llvm_constraints.items, ",")) llvm_constraints.items.len -= 1;
7518
75307519 const asm_source = std.mem.sliceAsBytes(self.air.extra.items[extra_i..])[0..extra.data.source_len];
75317520
75327521 // hackety hacks until stage2 has proper inline asm in the frontend.
......@@ -13206,3 +13195,257 @@ fn maxIntConst(b: *Builder, max_ty: Type, as_ty: Builder.Type, zcu: *const Zcu)
1320613195 try res.setTwosCompIntLimit(.max, info.signedness, info.bits);
1320713196 return b.bigIntConst(as_ty, res.toConst());
1320813197}
13198
13199/// Appends zero or more LLVM constraints to `llvm_constraints`, returning how many were added.
13200fn appendConstraints(
13201 gpa: Allocator,
13202 llvm_constraints: *std.ArrayListUnmanaged(u8),
13203 zig_name: []const u8,
13204 target: *const std.Target,
13205) error{OutOfMemory}!usize {
13206 switch (target.cpu.arch) {
13207 .mips, .mipsel, .mips64, .mips64el => if (mips_clobber_overrides.get(zig_name)) |llvm_tag| {
13208 const llvm_name = @tagName(llvm_tag);
13209 try llvm_constraints.ensureUnusedCapacity(gpa, llvm_name.len + 4);
13210 llvm_constraints.appendSliceAssumeCapacity("~{");
13211 llvm_constraints.appendSliceAssumeCapacity(llvm_name);
13212 llvm_constraints.appendSliceAssumeCapacity("},");
13213 return 1;
13214 },
13215 else => {},
13216 }
13217
13218 try llvm_constraints.ensureUnusedCapacity(gpa, zig_name.len + 4);
13219 llvm_constraints.appendSliceAssumeCapacity("~{");
13220 llvm_constraints.appendSliceAssumeCapacity(zig_name);
13221 llvm_constraints.appendSliceAssumeCapacity("},");
13222 return 1;
13223}
13224
13225const mips_clobber_overrides = std.StaticStringMap(enum {
13226 @"$msair",
13227 @"$msacsr",
13228 @"$msaaccess",
13229 @"$msasave",
13230 @"$msamodify",
13231 @"$msarequest",
13232 @"$msamap",
13233 @"$msaunmap",
13234 @"$f0",
13235 @"$f1",
13236 @"$f2",
13237 @"$f3",
13238 @"$f4",
13239 @"$f5",
13240 @"$f6",
13241 @"$f7",
13242 @"$f8",
13243 @"$f9",
13244 @"$f10",
13245 @"$f11",
13246 @"$f12",
13247 @"$f13",
13248 @"$f14",
13249 @"$f15",
13250 @"$f16",
13251 @"$f17",
13252 @"$f18",
13253 @"$f19",
13254 @"$f20",
13255 @"$f21",
13256 @"$f22",
13257 @"$f23",
13258 @"$f24",
13259 @"$f25",
13260 @"$f26",
13261 @"$f27",
13262 @"$f28",
13263 @"$f29",
13264 @"$f30",
13265 @"$f31",
13266 @"$fcc0",
13267 @"$fcc1",
13268 @"$fcc2",
13269 @"$fcc3",
13270 @"$fcc4",
13271 @"$fcc5",
13272 @"$fcc6",
13273 @"$fcc7",
13274 @"$w0",
13275 @"$w1",
13276 @"$w2",
13277 @"$w3",
13278 @"$w4",
13279 @"$w5",
13280 @"$w6",
13281 @"$w7",
13282 @"$w8",
13283 @"$w9",
13284 @"$w10",
13285 @"$w11",
13286 @"$w12",
13287 @"$w13",
13288 @"$w14",
13289 @"$w15",
13290 @"$w16",
13291 @"$w17",
13292 @"$w18",
13293 @"$w19",
13294 @"$w20",
13295 @"$w21",
13296 @"$w22",
13297 @"$w23",
13298 @"$w24",
13299 @"$w25",
13300 @"$w26",
13301 @"$w27",
13302 @"$w28",
13303 @"$w29",
13304 @"$w30",
13305 @"$w31",
13306 @"$0",
13307 @"$1",
13308 @"$2",
13309 @"$3",
13310 @"$4",
13311 @"$5",
13312 @"$6",
13313 @"$7",
13314 @"$8",
13315 @"$9",
13316 @"$10",
13317 @"$11",
13318 @"$12",
13319 @"$13",
13320 @"$14",
13321 @"$15",
13322 @"$16",
13323 @"$17",
13324 @"$18",
13325 @"$19",
13326 @"$20",
13327 @"$21",
13328 @"$22",
13329 @"$23",
13330 @"$24",
13331 @"$25",
13332 @"$26",
13333 @"$27",
13334 @"$28",
13335 @"$29",
13336 @"$30",
13337 @"$31",
13338}).initComptime(.{
13339 .{ "msa_ir", .@"$msair" },
13340 .{ "msa_csr", .@"$msacsr" },
13341 .{ "msa_access", .@"$msaaccess" },
13342 .{ "msa_save", .@"$msasave" },
13343 .{ "msa_modify", .@"$msamodify" },
13344 .{ "msa_request", .@"$msarequest" },
13345 .{ "msa_map", .@"$msamap" },
13346 .{ "msa_unmap", .@"$msaunmap" },
13347 .{ "f0", .@"$f0" },
13348 .{ "f1", .@"$f1" },
13349 .{ "f2", .@"$f2" },
13350 .{ "f3", .@"$f3" },
13351 .{ "f4", .@"$f4" },
13352 .{ "f5", .@"$f5" },
13353 .{ "f6", .@"$f6" },
13354 .{ "f7", .@"$f7" },
13355 .{ "f8", .@"$f8" },
13356 .{ "f9", .@"$f9" },
13357 .{ "f10", .@"$f10" },
13358 .{ "f11", .@"$f11" },
13359 .{ "f12", .@"$f12" },
13360 .{ "f13", .@"$f13" },
13361 .{ "f14", .@"$f14" },
13362 .{ "f15", .@"$f15" },
13363 .{ "f16", .@"$f16" },
13364 .{ "f17", .@"$f17" },
13365 .{ "f18", .@"$f18" },
13366 .{ "f19", .@"$f19" },
13367 .{ "f20", .@"$f20" },
13368 .{ "f21", .@"$f21" },
13369 .{ "f22", .@"$f22" },
13370 .{ "f23", .@"$f23" },
13371 .{ "f24", .@"$f24" },
13372 .{ "f25", .@"$f25" },
13373 .{ "f26", .@"$f26" },
13374 .{ "f27", .@"$f27" },
13375 .{ "f28", .@"$f28" },
13376 .{ "f29", .@"$f29" },
13377 .{ "f30", .@"$f30" },
13378 .{ "f31", .@"$f31" },
13379 .{ "fcc0", .@"$fcc0" },
13380 .{ "fcc1", .@"$fcc1" },
13381 .{ "fcc2", .@"$fcc2" },
13382 .{ "fcc3", .@"$fcc3" },
13383 .{ "fcc4", .@"$fcc4" },
13384 .{ "fcc5", .@"$fcc5" },
13385 .{ "fcc6", .@"$fcc6" },
13386 .{ "fcc7", .@"$fcc7" },
13387 .{ "w0", .@"$w0" },
13388 .{ "w1", .@"$w1" },
13389 .{ "w2", .@"$w2" },
13390 .{ "w3", .@"$w3" },
13391 .{ "w4", .@"$w4" },
13392 .{ "w5", .@"$w5" },
13393 .{ "w6", .@"$w6" },
13394 .{ "w7", .@"$w7" },
13395 .{ "w8", .@"$w8" },
13396 .{ "w9", .@"$w9" },
13397 .{ "w10", .@"$w10" },
13398 .{ "w11", .@"$w11" },
13399 .{ "w12", .@"$w12" },
13400 .{ "w13", .@"$w13" },
13401 .{ "w14", .@"$w14" },
13402 .{ "w15", .@"$w15" },
13403 .{ "w16", .@"$w16" },
13404 .{ "w17", .@"$w17" },
13405 .{ "w18", .@"$w18" },
13406 .{ "w19", .@"$w19" },
13407 .{ "w20", .@"$w20" },
13408 .{ "w21", .@"$w21" },
13409 .{ "w22", .@"$w22" },
13410 .{ "w23", .@"$w23" },
13411 .{ "w24", .@"$w24" },
13412 .{ "w25", .@"$w25" },
13413 .{ "w26", .@"$w26" },
13414 .{ "w27", .@"$w27" },
13415 .{ "w28", .@"$w28" },
13416 .{ "w29", .@"$w29" },
13417 .{ "w30", .@"$w30" },
13418 .{ "w31", .@"$w31" },
13419 .{ "r0", .@"$0" },
13420 .{ "r1", .@"$1" },
13421 .{ "r2", .@"$2" },
13422 .{ "r3", .@"$3" },
13423 .{ "r4", .@"$4" },
13424 .{ "r5", .@"$5" },
13425 .{ "r6", .@"$6" },
13426 .{ "r7", .@"$7" },
13427 .{ "r8", .@"$8" },
13428 .{ "r9", .@"$9" },
13429 .{ "r10", .@"$10" },
13430 .{ "r11", .@"$11" },
13431 .{ "r12", .@"$12" },
13432 .{ "r13", .@"$13" },
13433 .{ "r14", .@"$14" },
13434 .{ "r15", .@"$15" },
13435 .{ "r16", .@"$16" },
13436 .{ "r17", .@"$17" },
13437 .{ "r18", .@"$18" },
13438 .{ "r19", .@"$19" },
13439 .{ "r20", .@"$20" },
13440 .{ "r21", .@"$21" },
13441 .{ "r22", .@"$22" },
13442 .{ "r23", .@"$23" },
13443 .{ "r24", .@"$24" },
13444 .{ "r25", .@"$25" },
13445 .{ "r26", .@"$26" },
13446 .{ "r27", .@"$27" },
13447 .{ "r28", .@"$28" },
13448 .{ "r29", .@"$29" },
13449 .{ "r30", .@"$30" },
13450 .{ "r31", .@"$31" },
13451});