| ... | ... | @@ -117,11 +117,6 @@ pub const MCValue = union(enum) { |
| 117 | 117 | /// A pointer-sized integer that fits in a register. |
| 118 | 118 | /// If the type is a pointer, this is the pointer address in virtual address space. |
| 119 | 119 | immediate: u64, |
| 120 | | /// The constant was emitted into the code, at this offset. |
| 121 | | /// If the type is a pointer, it means the pointer address is embedded in the code. |
| 122 | | embedded_in_code: usize, |
| 123 | | /// The value is a pointer to a constant which was emitted into the code, at this offset. |
| 124 | | ptr_embedded_in_code: usize, |
| 125 | 120 | /// The value is in a target-specific register. |
| 126 | 121 | register: Register, |
| 127 | 122 | /// The value is in memory at a hard-coded address. |
| ... | ... | @@ -149,7 +144,7 @@ pub const MCValue = union(enum) { |
| 149 | 144 | |
| 150 | 145 | fn isMemory(mcv: MCValue) bool { |
| 151 | 146 | return switch (mcv) { |
| 152 | | .embedded_in_code, .memory, .stack_offset => true, |
| 147 | .memory, .stack_offset => true, |
| 153 | 148 | else => false, |
| 154 | 149 | }; |
| 155 | 150 | } |
| ... | ... | @@ -168,12 +163,10 @@ pub const MCValue = union(enum) { |
| 168 | 163 | .dead => unreachable, |
| 169 | 164 | |
| 170 | 165 | .immediate, |
| 171 | | .embedded_in_code, |
| 172 | 166 | .memory, |
| 173 | 167 | .compare_flags_unsigned, |
| 174 | 168 | .compare_flags_signed, |
| 175 | 169 | .ptr_stack_offset, |
| 176 | | .ptr_embedded_in_code, |
| 177 | 170 | .undef, |
| 178 | 171 | => false, |
| 179 | 172 | |
| ... | ... | @@ -2437,12 +2430,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2437 | 2430 | .ptr_stack_offset => |off| { |
| 2438 | 2431 | try self.setRegOrMem(elem_ty, dst_mcv, .{ .stack_offset = off }); |
| 2439 | 2432 | }, |
| 2440 | | .ptr_embedded_in_code => |off| { |
| 2441 | | try self.setRegOrMem(elem_ty, dst_mcv, .{ .embedded_in_code = off }); |
| 2442 | | }, |
| 2443 | | .embedded_in_code => { |
| 2444 | | return self.fail("TODO implement loading from MCValue.embedded_in_code", .{}); |
| 2445 | | }, |
| 2446 | 2433 | .register => |reg| { |
| 2447 | 2434 | self.register_manager.freezeRegs(&.{reg}); |
| 2448 | 2435 | defer self.register_manager.unfreezeRegs(&.{reg}); |
| ... | ... | @@ -2452,7 +2439,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2452 | 2439 | .undef => unreachable, |
| 2453 | 2440 | .compare_flags_unsigned => unreachable, |
| 2454 | 2441 | .compare_flags_signed => unreachable, |
| 2455 | | .embedded_in_code => unreachable, |
| 2456 | 2442 | .register => |dst_reg| { |
| 2457 | 2443 | // mov dst_reg, [reg] |
| 2458 | 2444 | _ = try self.addInst(.{ |
| ... | ... | @@ -2567,12 +2553,6 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2567 | 2553 | .ptr_stack_offset => |off| { |
| 2568 | 2554 | try self.genSetStack(value_ty, off, value, .{}); |
| 2569 | 2555 | }, |
| 2570 | | .ptr_embedded_in_code => |off| { |
| 2571 | | try self.setRegOrMem(value_ty, .{ .embedded_in_code = off }, value); |
| 2572 | | }, |
| 2573 | | .embedded_in_code => { |
| 2574 | | return self.fail("TODO implement storing to MCValue.embedded_in_code", .{}); |
| 2575 | | }, |
| 2576 | 2556 | .register => |reg| { |
| 2577 | 2557 | self.register_manager.freezeRegs(&.{reg}); |
| 2578 | 2558 | defer self.register_manager.unfreezeRegs(&.{reg}); |
| ... | ... | @@ -3025,7 +3005,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 3025 | 3005 | .compare_flags_unsigned => unreachable, |
| 3026 | 3006 | .compare_flags_signed => unreachable, |
| 3027 | 3007 | .ptr_stack_offset => unreachable, |
| 3028 | | .ptr_embedded_in_code => unreachable, |
| 3029 | 3008 | .register => |dst_reg| { |
| 3030 | 3009 | switch (src_mcv) { |
| 3031 | 3010 | .none => unreachable, |
| ... | ... | @@ -3037,7 +3016,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 3037 | 3016 | const reg = try self.copyToTmpRegister(dst_ty, src_mcv); |
| 3038 | 3017 | return self.genBinMathOpMir(mir_tag, dst_ty, dst_mcv, .{ .register = reg }); |
| 3039 | 3018 | }, |
| 3040 | | .ptr_embedded_in_code => unreachable, |
| 3041 | 3019 | .register => |src_reg| { |
| 3042 | 3020 | _ = try self.addInst(.{ |
| 3043 | 3021 | .tag = mir_tag, |
| ... | ... | @@ -3057,7 +3035,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 3057 | 3035 | .data = .{ .imm = @truncate(u32, imm) }, |
| 3058 | 3036 | }); |
| 3059 | 3037 | }, |
| 3060 | | .embedded_in_code, |
| 3061 | 3038 | .memory, |
| 3062 | 3039 | .got_load, |
| 3063 | 3040 | .direct_load, |
| ... | ... | @@ -3099,7 +3076,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 3099 | 3076 | .undef => return self.genSetStack(dst_ty, off, .undef, .{}), |
| 3100 | 3077 | .dead, .unreach => unreachable, |
| 3101 | 3078 | .ptr_stack_offset => unreachable, |
| 3102 | | .ptr_embedded_in_code => unreachable, |
| 3103 | 3079 | .register => |src_reg| { |
| 3104 | 3080 | _ = try self.addInst(.{ |
| 3105 | 3081 | .tag = mir_tag, |
| ... | ... | @@ -3141,7 +3117,7 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 3141 | 3117 | .data = .{ .payload = payload }, |
| 3142 | 3118 | }); |
| 3143 | 3119 | }, |
| 3144 | | .embedded_in_code, .memory, .stack_offset => { |
| 3120 | .memory, .stack_offset => { |
| 3145 | 3121 | return self.fail("TODO implement x86 ADD/SUB/CMP source memory", .{}); |
| 3146 | 3122 | }, |
| 3147 | 3123 | .got_load, .direct_load => { |
| ... | ... | @@ -3155,7 +3131,7 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 3155 | 3131 | }, |
| 3156 | 3132 | } |
| 3157 | 3133 | }, |
| 3158 | | .embedded_in_code, .memory => { |
| 3134 | .memory => { |
| 3159 | 3135 | return self.fail("TODO implement x86 ADD/SUB/CMP destination memory", .{}); |
| 3160 | 3136 | }, |
| 3161 | 3137 | .got_load, .direct_load => { |
| ... | ... | @@ -3173,14 +3149,12 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) ! |
| 3173 | 3149 | .compare_flags_unsigned => unreachable, |
| 3174 | 3150 | .compare_flags_signed => unreachable, |
| 3175 | 3151 | .ptr_stack_offset => unreachable, |
| 3176 | | .ptr_embedded_in_code => unreachable, |
| 3177 | 3152 | .register => |dst_reg| { |
| 3178 | 3153 | switch (src_mcv) { |
| 3179 | 3154 | .none => unreachable, |
| 3180 | 3155 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), |
| 3181 | 3156 | .dead, .unreach => unreachable, |
| 3182 | 3157 | .ptr_stack_offset => unreachable, |
| 3183 | | .ptr_embedded_in_code => unreachable, |
| 3184 | 3158 | .register => |src_reg| { |
| 3185 | 3159 | // register, register |
| 3186 | 3160 | _ = try self.addInst(.{ |
| ... | ... | @@ -3222,7 +3196,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) ! |
| 3222 | 3196 | .data = .{ .imm = @bitCast(u32, -off) }, |
| 3223 | 3197 | }); |
| 3224 | 3198 | }, |
| 3225 | | .embedded_in_code, .memory => { |
| 3199 | .memory => { |
| 3226 | 3200 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 3227 | 3201 | }, |
| 3228 | 3202 | .got_load, .direct_load => { |
| ... | ... | @@ -3242,7 +3216,6 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) ! |
| 3242 | 3216 | .undef => return self.genSetStack(dst_ty, off, .undef, .{}), |
| 3243 | 3217 | .dead, .unreach => unreachable, |
| 3244 | 3218 | .ptr_stack_offset => unreachable, |
| 3245 | | .ptr_embedded_in_code => unreachable, |
| 3246 | 3219 | .register => |src_reg| { |
| 3247 | 3220 | // copy dst to a register |
| 3248 | 3221 | const dst_reg = try self.copyToTmpRegister(dst_ty, dst_mcv); |
| ... | ... | @@ -3263,7 +3236,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) ! |
| 3263 | 3236 | _ = imm; |
| 3264 | 3237 | return self.fail("TODO implement x86 multiply source immediate", .{}); |
| 3265 | 3238 | }, |
| 3266 | | .embedded_in_code, .memory, .stack_offset => { |
| 3239 | .memory, .stack_offset => { |
| 3267 | 3240 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 3268 | 3241 | }, |
| 3269 | 3242 | .got_load, .direct_load => { |
| ... | ... | @@ -3277,7 +3250,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) ! |
| 3277 | 3250 | }, |
| 3278 | 3251 | } |
| 3279 | 3252 | }, |
| 3280 | | .embedded_in_code, .memory => { |
| 3253 | .memory => { |
| 3281 | 3254 | return self.fail("TODO implement x86 multiply destination memory", .{}); |
| 3282 | 3255 | }, |
| 3283 | 3256 | .got_load, .direct_load => { |
| ... | ... | @@ -3396,14 +3369,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3396 | 3369 | .ptr_stack_offset => { |
| 3397 | 3370 | return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{}); |
| 3398 | 3371 | }, |
| 3399 | | .ptr_embedded_in_code => { |
| 3400 | | return self.fail("TODO implement calling with MCValue.ptr_embedded_in_code arg", .{}); |
| 3401 | | }, |
| 3402 | 3372 | .undef => unreachable, |
| 3403 | 3373 | .immediate => unreachable, |
| 3404 | 3374 | .unreach => unreachable, |
| 3405 | 3375 | .dead => unreachable, |
| 3406 | | .embedded_in_code => unreachable, |
| 3407 | 3376 | .memory => unreachable, |
| 3408 | 3377 | .got_load => unreachable, |
| 3409 | 3378 | .direct_load => unreachable, |
| ... | ... | @@ -4626,7 +4595,6 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 4626 | 4595 | const abi_size = ty.abiSize(self.target.*); |
| 4627 | 4596 | switch (mcv) { |
| 4628 | 4597 | .dead => unreachable, |
| 4629 | | .ptr_embedded_in_code => unreachable, |
| 4630 | 4598 | .unreach, .none => return, |
| 4631 | 4599 | .undef => { |
| 4632 | 4600 | if (abi_size <= 8) { |
| ... | ... | @@ -4677,13 +4645,6 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 4677 | 4645 | else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}), |
| 4678 | 4646 | } |
| 4679 | 4647 | }, |
| 4680 | | .embedded_in_code => { |
| 4681 | | if (abi_size <= 8) { |
| 4682 | | const reg = try self.copyToTmpRegister(ty, mcv); |
| 4683 | | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 4684 | | } |
| 4685 | | return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}); |
| 4686 | | }, |
| 4687 | 4648 | .memory, |
| 4688 | 4649 | .direct_load, |
| 4689 | 4650 | .got_load, |
| ... | ... | @@ -4731,7 +4692,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 4731 | 4692 | const abi_size = ty.abiSize(self.target.*); |
| 4732 | 4693 | switch (mcv) { |
| 4733 | 4694 | .dead => unreachable, |
| 4734 | | .ptr_embedded_in_code => unreachable, |
| 4735 | 4695 | .unreach, .none => return, // Nothing to do. |
| 4736 | 4696 | .undef => { |
| 4737 | 4697 | if (!self.wantSafety()) |
| ... | ... | @@ -4870,7 +4830,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 4870 | 4830 | } |
| 4871 | 4831 | }, |
| 4872 | 4832 | .memory, |
| 4873 | | .embedded_in_code, |
| 4874 | 4833 | .got_load, |
| 4875 | 4834 | .direct_load, |
| 4876 | 4835 | => { |
| ... | ... | @@ -5222,7 +5181,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5222 | 5181 | .data = .{ .imm = @bitCast(u32, -off) }, |
| 5223 | 5182 | }); |
| 5224 | 5183 | }, |
| 5225 | | .ptr_embedded_in_code => unreachable, |
| 5226 | 5184 | .unreach, .none => return, // Nothing to do. |
| 5227 | 5185 | .undef => { |
| 5228 | 5186 | if (!self.wantSafety()) |
| ... | ... | @@ -5304,18 +5262,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5304 | 5262 | .data = .{ .payload = payload }, |
| 5305 | 5263 | }); |
| 5306 | 5264 | }, |
| 5307 | | .embedded_in_code => |code_offset| { |
| 5308 | | // We need the offset from RIP in a signed i32 twos complement. |
| 5309 | | const payload = try self.addExtra(Mir.Imm64.encode(code_offset)); |
| 5310 | | _ = try self.addInst(.{ |
| 5311 | | .tag = .lea, |
| 5312 | | .ops = (Mir.Ops{ |
| 5313 | | .reg1 = reg, |
| 5314 | | .flags = 0b01, |
| 5315 | | }).encode(), |
| 5316 | | .data = .{ .payload = payload }, |
| 5317 | | }); |
| 5318 | | }, |
| 5319 | 5265 | .register => |src_reg| { |
| 5320 | 5266 | // If the registers are the same, nothing to do. |
| 5321 | 5267 | if (src_reg.id() == reg.id()) |