| ... | @@ -2274,35 +2274,39 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2274,35 +2274,39 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2274 | return self.genSetReg(src, reg, .{ .immediate = 0xaaaaaaaa }); | 2274 | return self.genSetReg(src, reg, .{ .immediate = 0xaaaaaaaa }); |
| 2275 | }, | 2275 | }, |
| 2276 | .immediate => |x| { | 2276 | .immediate => |x| { |
| 2277 | // TODO better analysis of x to determine the | 2277 | if (x > math.maxInt(u32)) return self.fail(src, "ARM registers are 32-bit wide", .{}); |
| 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 | | |
| 2293 | | 2278 | |
| 2294 | // immediate: 0xaabbccdd | 2279 | if (Instruction.Operand.fromU32(@intCast(u32, x))) |op| { |
| 2295 | // mov reg, #0xaa | 2280 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, reg, op).toU32()); |
| 2296 | // orr reg, reg, #0xbb, 24 | 2281 | } else if (Instruction.Operand.fromU32(~@intCast(u32, x))) |op| { |
| 2297 | // orr reg, reg, #0xcc, 16 | 2282 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mvn(.al, reg, op).toU32()); |
| 2298 | // orr reg, reg, #0xdd, 8 | 2283 | } else if (x <= math.maxInt(u16)) { |
| 2299 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, reg, Instruction.Operand.imm(@truncate(u8, x), 0)).toU32()); | 2284 | if (Target.arm.featureSetHas(self.target.cpu.features, .has_v7)) { |
| 2300 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 8), 12)).toU32()); | 2285 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movw(.al, reg, @intCast(u16, x)).toU32()); |
| 2301 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 16), 8)).toU32()); | 2286 | } else { |
| 2302 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, reg, reg, Instruction.Operand.imm(@truncate(u8, x >> 24), 4)).toU32()); | 2287 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, reg, Instruction.Operand.imm(@truncate(u8, x), 0)).toU32()); |
| 2303 | return; | 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 | } else { | 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 | .register => |src_reg| { | 2312 | .register => |src_reg| { |