| ... | ... | @@ -249,6 +249,37 @@ const Function = struct { |
| 249 | 249 | .embedded_in_code => return self.fail(src, "TODO implement x86_64 genSetReg %rax = embedded_in_code", .{}), |
| 250 | 250 | .register => return self.fail(src, "TODO implement x86_64 genSetReg %rax = register", .{}), |
| 251 | 251 | }, |
| 252 | .rdx => switch (mcv) { |
| 253 | .none, .unreach => unreachable, |
| 254 | .immediate => |x| { |
| 255 | // Setting the edx register zeroes the upper part of rdx, so if the number is small |
| 256 | // enough, that is preferable. |
| 257 | // Best case: zero |
| 258 | // 31 d2 xor edx,edx |
| 259 | if (x == 0) { |
| 260 | return self.code.appendSlice(&[_]u8{ 0x31, 0xd2 }); |
| 261 | } |
| 262 | // Next best case: set edx with 4 bytes |
| 263 | // ba 04 03 02 01 mov edx,0x1020304 |
| 264 | if (x <= std.math.maxInt(u32)) { |
| 265 | try self.code.resize(self.code.items.len + 5); |
| 266 | self.code.items[self.code.items.len - 5] = 0xba; |
| 267 | const imm_ptr = self.code.items[self.code.items.len - 4 ..][0..4]; |
| 268 | mem.writeIntLittle(u32, imm_ptr, @intCast(u32, x)); |
| 269 | return; |
| 270 | } |
| 271 | // Worst case: set rdx with 8 bytes |
| 272 | // 48 ba 08 07 06 05 04 03 02 01 movabs rdx,0x0102030405060708 |
| 273 | try self.code.resize(self.code.items.len + 10); |
| 274 | self.code.items[self.code.items.len - 10] = 0x48; |
| 275 | self.code.items[self.code.items.len - 9] = 0xba; |
| 276 | const imm_ptr = self.code.items[self.code.items.len - 8 ..][0..8]; |
| 277 | mem.writeIntLittle(u64, imm_ptr, x); |
| 278 | return; |
| 279 | }, |
| 280 | .embedded_in_code => return self.fail(src, "TODO implement x86_64 genSetReg %rdx = embedded_in_code", .{}), |
| 281 | .register => return self.fail(src, "TODO implement x86_64 genSetReg %rdx = register", .{}), |
| 282 | }, |
| 252 | 283 | .rdi => switch (mcv) { |
| 253 | 284 | .none, .unreach => unreachable, |
| 254 | 285 | .immediate => |x| { |
| ... | ... | @@ -305,12 +336,6 @@ const Function = struct { |
| 305 | 336 | }, |
| 306 | 337 | .register => return self.fail(src, "TODO implement x86_64 genSetReg %rsi = register", .{}), |
| 307 | 338 | }, |
| 308 | | .rdx => switch (mcv) { |
| 309 | | .none, .unreach => unreachable, |
| 310 | | .immediate => return self.fail(src, "TODO implement x86_64 genSetReg %rdx = immediate", .{}), |
| 311 | | .embedded_in_code => return self.fail(src, "TODO implement x86_64 genSetReg %rdx = embedded_in_code", .{}), |
| 312 | | .register => return self.fail(src, "TODO implement x86_64 genSetReg %rdx = register", .{}), |
| 313 | | }, |
| 314 | 339 | else => return self.fail(src, "TODO implement genSetReg for x86_64 '{}'", .{@tagName(reg)}), |
| 315 | 340 | }, |
| 316 | 341 | else => return self.fail(src, "TODO implement genSetReg for more architectures", .{}), |