| ... | @@ -1246,6 +1246,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -1246,6 +1246,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1246 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.rsb(.al, dst_reg, dst_reg, operand).toU32()); | 1246 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.rsb(.al, dst_reg, dst_reg, operand).toU32()); |
| 1247 | } | 1247 | } |
| 1248 | }, | 1248 | }, |
| | 1249 | .booland => { |
| | 1250 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.@"and"(.al, dst_reg, dst_reg, operand).toU32()); |
| | 1251 | }, |
| | 1252 | .boolor => { |
| | 1253 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, dst_reg, dst_reg, operand).toU32()); |
| | 1254 | }, |
| 1249 | .not => { | 1255 | .not => { |
| 1250 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.eor(.al, dst_reg, dst_reg, operand).toU32()); | 1256 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.eor(.al, dst_reg, dst_reg, operand).toU32()); |
| 1251 | }, | 1257 | }, |
| ... | @@ -2209,7 +2215,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2209,7 +2215,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2209 | .booland => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 4, 0x20), | 2215 | .booland => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 4, 0x20), |
| 2210 | // lhs OR rhs | 2216 | // lhs OR rhs |
| 2211 | .boolor => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 1, 0x08), | 2217 | .boolor => return try self.genX8664BinMath(&inst.base, inst.lhs, inst.rhs, 1, 0x08), |
| 2212 | else => unreachable, | 2218 | else => unreachable, // Not a boolean operation |
| | 2219 | }, |
| | 2220 | .arm, .armeb => switch (inst.base.tag) { |
| | 2221 | .booland => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .booland), |
| | 2222 | .boolor => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .boolor), |
| | 2223 | else => unreachable, // Not a boolean operation |
| 2213 | }, | 2224 | }, |
| 2214 | else => return self.fail(inst.base.src, "TODO implement boolean operations for {}", .{self.target.cpu.arch}), | 2225 | else => return self.fail(inst.base.src, "TODO implement boolean operations for {}", .{self.target.cpu.arch}), |
| 2215 | } | 2226 | } |
| ... | @@ -2464,14 +2475,23 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2464,14 +2475,23 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2464 | return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{}); | 2475 | return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{}); |
| 2465 | }, | 2476 | }, |
| 2466 | .register => |reg| { | 2477 | .register => |reg| { |
| 2467 | // TODO: strb, strh | 2478 | // TODO: strh |
| 2468 | if (stack_offset <= math.maxInt(u12)) { | 2479 | const offset = if (stack_offset <= math.maxInt(u12)) blk: { |
| 2469 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.str(.al, reg, .fp, .{ | 2480 | break :blk Instruction.Offset.imm(@intCast(u12, stack_offset)); |
| 2470 | .offset = Instruction.Offset.imm(@intCast(u12, stack_offset)), | 2481 | } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = stack_offset }), 0); |
| | 2482 | |
| | 2483 | const abi_size = ty.abiSize(self.target.*); |
| | 2484 | switch (abi_size) { |
| | 2485 | 1 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.strb(.al, reg, .fp, .{ |
| | 2486 | .offset = offset, |
| 2471 | .positive = false, | 2487 | .positive = false, |
| 2472 | }).toU32()); | 2488 | }).toU32()), |
| 2473 | } else { | 2489 | 2 => return self.fail(src, "TODO implement strh", .{}), |
| 2474 | return self.fail(src, "TODO genSetStack with larger offsets", .{}); | 2490 | 4 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.str(.al, reg, .fp, .{ |
| | 2491 | .offset = offset, |
| | 2492 | .positive = false, |
| | 2493 | }).toU32()), |
| | 2494 | else => return self.fail(src, "TODO a type of size {} is not allowed in a register", .{abi_size}), |
| 2475 | } | 2495 | } |
| 2476 | }, | 2496 | }, |
| 2477 | .memory => |vaddr| { | 2497 | .memory => |vaddr| { |
| ... | @@ -2642,15 +2662,26 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2642,15 +2662,26 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2642 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, reg, .{ .offset = Instruction.Offset.none }).toU32()); | 2662 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, reg, .{ .offset = Instruction.Offset.none }).toU32()); |
| 2643 | }, | 2663 | }, |
| 2644 | .stack_offset => |unadjusted_off| { | 2664 | .stack_offset => |unadjusted_off| { |
| 2645 | // TODO: ldrb, ldrh | 2665 | // TODO: ldrh |
| 2646 | // TODO: maybe addressing from sp instead of fp | 2666 | // TODO: maybe addressing from sp instead of fp |
| 2647 | if (unadjusted_off <= math.maxInt(u12)) { | 2667 | const offset = if (unadjusted_off <= math.maxInt(u12)) blk: { |
| 2648 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, .fp, .{ | 2668 | break :blk Instruction.Offset.imm(@intCast(u12, unadjusted_off)); |
| 2649 | .offset = Instruction.Offset.imm(@intCast(u12, unadjusted_off)), | 2669 | } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = unadjusted_off }), 0); |
| | 2670 | |
| | 2671 | // TODO: supply type information to genSetReg as we do to genSetStack |
| | 2672 | // const abi_size = ty.abiSize(self.target.*); |
| | 2673 | const abi_size = 4; |
| | 2674 | switch (abi_size) { |
| | 2675 | 1 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldrb(.al, reg, .fp, .{ |
| | 2676 | .offset = offset, |
| 2650 | .positive = false, | 2677 | .positive = false, |
| 2651 | }).toU32()); | 2678 | }).toU32()), |
| 2652 | } else { | 2679 | 2 => return self.fail(src, "TODO implement strh", .{}), |
| 2653 | return self.fail(src, "TODO genSetReg with larger stack offset", .{}); | 2680 | 4 => writeInt(u32, try self.code.addManyAsArray(4), Instruction.ldr(.al, reg, .fp, .{ |
| | 2681 | .offset = offset, |
| | 2682 | .positive = false, |
| | 2683 | }).toU32()), |
| | 2684 | else => return self.fail(src, "TODO a type of size {} is not allowed in a register", .{abi_size}), |
| 2654 | } | 2685 | } |
| 2655 | }, | 2686 | }, |
| 2656 | else => return self.fail(src, "TODO implement getSetReg for arm {}", .{mcv}), | 2687 | else => return self.fail(src, "TODO implement getSetReg for arm {}", .{mcv}), |