diff options
| author | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2020-12-20 14:50:48 +0100 |
|---|---|---|
| committer | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2020-12-21 19:24:21 +0100 |
| commit | 82236a502959d39b97c783dc409a9a5b720e6e8b (patch) | |
| tree | a6f741bab53ea91bafe9403afc815cc33c1ad92c /src/codegen.zig | |
| parent | 286077fec8f381c7b4d4d5bf351d963564a1dd69 (diff) | |
| download | zig-82236a502959d39b97c783dc409a9a5b720e6e8b.tar.gz zig-82236a502959d39b97c783dc409a9a5b720e6e8b.zip | |
stage2 ARM: implement basic binary bitwise operations
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index 3b0a383a71..01deb13c0e 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -764,6 +764,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .arg => return self.genArg(inst.castTag(.arg).?), .assembly => return self.genAsm(inst.castTag(.assembly).?), .bitcast => return self.genBitCast(inst.castTag(.bitcast).?), + .bitand => return self.genBitAnd(inst.castTag(.bitand).?), + .bitor => return self.genBitOr(inst.castTag(.bitor).?), .block => return self.genBlock(inst.castTag(.block).?), .br => return self.genBr(inst.castTag(.br).?), .breakpoint => return self.genBreakpoint(inst.src), @@ -799,6 +801,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .unwrap_optional => return self.genUnwrapOptional(inst.castTag(.unwrap_optional).?), .wrap_optional => return self.genWrapOptional(inst.castTag(.wrap_optional).?), .varptr => return self.genVarPtr(inst.castTag(.varptr).?), + .xor => return self.genXor(inst.castTag(.xor).?), } } @@ -1009,6 +1012,36 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { } } + fn genBitAnd(self: *Self, inst: *ir.Inst.BinOp) !MCValue { + // No side effects, so if it's unreferenced, do nothing. + if (inst.base.isUnused()) + return MCValue.dead; + switch (arch) { + .arm, .armeb => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .bitand), + else => return self.fail(inst.base.src, "TODO implement bitwise and for {}", .{self.target.cpu.arch}), + } + } + + fn genBitOr(self: *Self, inst: *ir.Inst.BinOp) !MCValue { + // No side effects, so if it's unreferenced, do nothing. + if (inst.base.isUnused()) + return MCValue.dead; + switch (arch) { + .arm, .armeb => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .bitor), + else => return self.fail(inst.base.src, "TODO implement bitwise or for {}", .{self.target.cpu.arch}), + } + } + + fn genXor(self: *Self, inst: *ir.Inst.BinOp) !MCValue { + // No side effects, so if it's unreferenced, do nothing. + if (inst.base.isUnused()) + return MCValue.dead; + switch (arch) { + .arm, .armeb => return try self.genArmBinOp(&inst.base, inst.lhs, inst.rhs, .xor), + else => return self.fail(inst.base.src, "TODO implement xor for {}", .{self.target.cpu.arch}), + } + } + fn genUnwrapOptional(self: *Self, inst: *ir.Inst.UnOp) !MCValue { // No side effects, so if it's unreferenced, do nothing. if (inst.base.isUnused()) @@ -1251,13 +1284,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { writeInt(u32, try self.code.addManyAsArray(4), Instruction.rsb(.al, dst_reg, dst_reg, operand).toU32()); } }, - .booland => { + .booland, .bitand => { writeInt(u32, try self.code.addManyAsArray(4), Instruction.@"and"(.al, dst_reg, dst_reg, operand).toU32()); }, - .boolor => { + .boolor, .bitor => { writeInt(u32, try self.code.addManyAsArray(4), Instruction.orr(.al, dst_reg, dst_reg, operand).toU32()); }, - .not => { + .not, .xor => { writeInt(u32, try self.code.addManyAsArray(4), Instruction.eor(.al, dst_reg, dst_reg, operand).toU32()); }, else => unreachable, // not a binary instruction |
