| ... | ... | @@ -11334,43 +11334,40 @@ fn zirAsm( |
| 11334 | 11334 | try sema.requireRuntimeBlock(block, src); |
| 11335 | 11335 | } |
| 11336 | 11336 | |
| 11337 | | if (outputs_len > 1) { |
| 11338 | | return sema.fail(block, src, "TODO implement Sema for asm with more than 1 output", .{}); |
| 11339 | | } |
| 11340 | | |
| 11341 | 11337 | var extra_i = extra.end; |
| 11342 | 11338 | var output_type_bits = extra.data.output_type_bits; |
| 11343 | 11339 | var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len; |
| 11344 | 11340 | |
| 11345 | | const Output = struct { |
| 11346 | | constraint: []const u8, |
| 11347 | | name: []const u8, |
| 11348 | | ty: Type, |
| 11349 | | }; |
| 11350 | | const output: ?Output = if (outputs_len == 0) null else blk: { |
| 11341 | const ConstraintName = struct { c: []const u8, n: []const u8 }; |
| 11342 | const out_args = try sema.arena.alloc(Air.Inst.Ref, outputs_len); |
| 11343 | const outputs = try sema.arena.alloc(ConstraintName, outputs_len); |
| 11344 | var expr_ty = Air.Inst.Ref.void_type; |
| 11345 | |
| 11346 | for (out_args) |*arg, out_i| { |
| 11351 | 11347 | const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i); |
| 11352 | 11348 | extra_i = output.end; |
| 11353 | 11349 | |
| 11354 | 11350 | const is_type = @truncate(u1, output_type_bits) != 0; |
| 11355 | 11351 | output_type_bits >>= 1; |
| 11356 | 11352 | |
| 11357 | | if (!is_type) { |
| 11358 | | return sema.fail(block, src, "TODO implement Sema for asm with non `->` output", .{}); |
| 11353 | if (is_type) { |
| 11354 | // Indicate the output is the asm instruction return value. |
| 11355 | arg.* = .none; |
| 11356 | const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand); |
| 11357 | expr_ty = try sema.addType(out_ty); |
| 11358 | } else { |
| 11359 | arg.* = try sema.resolveInst(output.data.operand); |
| 11359 | 11360 | } |
| 11360 | 11361 | |
| 11361 | 11362 | const constraint = sema.code.nullTerminatedString(output.data.constraint); |
| 11362 | 11363 | const name = sema.code.nullTerminatedString(output.data.name); |
| 11363 | 11364 | needed_capacity += (constraint.len + name.len + (2 + 3)) / 4; |
| 11364 | 11365 | |
| 11365 | | break :blk Output{ |
| 11366 | | .constraint = constraint, |
| 11367 | | .name = name, |
| 11368 | | .ty = try sema.resolveType(block, ret_ty_src, output.data.operand), |
| 11369 | | }; |
| 11370 | | }; |
| 11366 | outputs[out_i] = .{ .c = constraint, .n = name }; |
| 11367 | } |
| 11371 | 11368 | |
| 11372 | 11369 | const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len); |
| 11373 | | const inputs = try sema.arena.alloc(struct { c: []const u8, n: []const u8 }, inputs_len); |
| 11370 | const inputs = try sema.arena.alloc(ConstraintName, inputs_len); |
| 11374 | 11371 | |
| 11375 | 11372 | for (args) |*arg, arg_i| { |
| 11376 | 11373 | const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i); |
| ... | ... | @@ -11405,7 +11402,7 @@ fn zirAsm( |
| 11405 | 11402 | const asm_air = try block.addInst(.{ |
| 11406 | 11403 | .tag = .assembly, |
| 11407 | 11404 | .data = .{ .ty_pl = .{ |
| 11408 | | .ty = if (output) |o| try sema.addType(o.ty) else Air.Inst.Ref.void_type, |
| 11405 | .ty = expr_ty, |
| 11409 | 11406 | .payload = sema.addExtraAssumeCapacity(Air.Asm{ |
| 11410 | 11407 | .source_len = @intCast(u32, asm_source.len), |
| 11411 | 11408 | .outputs_len = outputs_len, |
| ... | ... | @@ -11414,18 +11411,15 @@ fn zirAsm( |
| 11414 | 11411 | }), |
| 11415 | 11412 | } }, |
| 11416 | 11413 | }); |
| 11417 | | if (output != null) { |
| 11418 | | // Indicate the output is the asm instruction return value. |
| 11419 | | sema.air_extra.appendAssumeCapacity(@enumToInt(Air.Inst.Ref.none)); |
| 11420 | | } |
| 11414 | sema.appendRefsAssumeCapacity(out_args); |
| 11421 | 11415 | sema.appendRefsAssumeCapacity(args); |
| 11422 | | if (output) |o| { |
| 11416 | for (outputs) |o| { |
| 11423 | 11417 | const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice()); |
| 11424 | | mem.copy(u8, buffer, o.constraint); |
| 11425 | | buffer[o.constraint.len] = 0; |
| 11426 | | mem.copy(u8, buffer[o.constraint.len + 1 ..], o.name); |
| 11427 | | buffer[o.constraint.len + 1 + o.name.len] = 0; |
| 11428 | | sema.air_extra.items.len += (o.constraint.len + o.name.len + (2 + 3)) / 4; |
| 11418 | mem.copy(u8, buffer, o.c); |
| 11419 | buffer[o.c.len] = 0; |
| 11420 | mem.copy(u8, buffer[o.c.len + 1 ..], o.n); |
| 11421 | buffer[o.c.len + 1 + o.n.len] = 0; |
| 11422 | sema.air_extra.items.len += (o.c.len + o.n.len + (2 + 3)) / 4; |
| 11429 | 11423 | } |
| 11430 | 11424 | for (inputs) |input| { |
| 11431 | 11425 | const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice()); |