| ... | ... | @@ -2274,35 +2274,39 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2274 | 2274 | return self.genSetReg(src, reg, .{ .immediate = 0xaaaaaaaa }); |
| 2275 | 2275 | }, |
| 2276 | 2276 | .immediate => |x| { |
| 2277 | | // TODO better analysis of x to determine the |
| 2278 | | // least amount of necessary instructions (use |
| 2279 | | // more intelligent rotating) |
| 2280 | | if (x <= math.maxInt(u8)) { |
| 2281 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, reg, Instruction.Operand.imm(@truncate(u8, x), 0)).toU32()); |
| 2282 | | return; |
| 2283 | | } else if (x <= math.maxInt(u16)) { |
| 2284 | | // TODO Use movw Note: Not supported on |
| 2285 | | // all ARM targets! |
| 2286 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, reg, Instruction.Operand.imm(@truncate(u8, x), 0)).toU32()); |
| 2287 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 8), 12)).toU32()); |
| 2288 | | } else if (x <= math.maxInt(u32)) { |
| 2289 | | // TODO Use movw and movt Note: Not |
| 2290 | | // supported on all ARM targets! Also TODO |
| 2291 | | // write constant to code and load |
| 2292 | | // relative to pc |
| 2277 | if (x > math.maxInt(u32)) return self.fail(src, "ARM registers are 32-bit wide", .{}); |
| 2293 | 2278 | |
| 2294 | | // immediate: 0xaabbccdd |
| 2295 | | // mov reg, #0xaa |
| 2296 | | // orr reg, reg, #0xbb, 24 |
| 2297 | | // orr reg, reg, #0xcc, 16 |
| 2298 | | // orr reg, reg, #0xdd, 8 |
| 2299 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, reg, Instruction.Operand.imm(@truncate(u8, x), 0)).toU32()); |
| 2300 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 8), 12)).toU32()); |
| 2301 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 16), 8)).toU32()); |
| 2302 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 24), 4)).toU32()); |
| 2303 | | return; |
| 2279 | if (Instruction.Operand.fromU32(@intCast(u32, x))) |op| { |
| 2280 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, reg, op).toU32()); |
| 2281 | } else if (Instruction.Operand.fromU32(~@intCast(u32, x))) |op| { |
| 2282 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mvn(.al, reg, op).toU32()); |
| 2283 | } else if (x <= math.maxInt(u16)) { |
| 2284 | if (Target.arm.featureSetHas(self.target.cpu.features, .has_v7)) { |
| 2285 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movw(.al, reg, @intCast(u16, x)).toU32()); |
| 2286 | } else { |
| 2287 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, reg, Instruction.Operand.imm(@truncate(u8, x), 0)).toU32()); |
| 2288 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 8), 12)).toU32()); |
| 2289 | } |
| 2304 | 2290 | } else { |
| 2305 | | return self.fail(src, "ARM registers are 32-bit wide", .{}); |
| 2291 | // TODO write constant to code and load |
| 2292 | // relative to pc |
| 2293 | if (Target.arm.featureSetHas(self.target.cpu.features, .has_v7)) { |
| 2294 | // immediate: 0xaaaabbbb |
| 2295 | // movw reg, #0xbbbb |
| 2296 | // movt reg, #0xaaaa |
| 2297 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movw(.al, reg, @truncate(u16, x)).toU32()); |
| 2298 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movt(.al, reg, @truncate(u16, x >> 16)).toU32()); |
| 2299 | } else { |
| 2300 | // immediate: 0xaabbccdd |
| 2301 | // mov reg, #0xaa |
| 2302 | // orr reg, reg, #0xbb, 24 |
| 2303 | // orr reg, reg, #0xcc, 16 |
| 2304 | // orr reg, reg, #0xdd, 8 |
| 2305 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, reg, Instruction.Operand.imm(@truncate(u8, x), 0)).toU32()); |
| 2306 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 8), 12)).toU32()); |
| 2307 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 16), 8)).toU32()); |
| 2308 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 24), 4)).toU32()); |
| 2309 | } |
| 2306 | 2310 | } |
| 2307 | 2311 | }, |
| 2308 | 2312 | .register => |src_reg| { |