aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-01-01 13:19:11 -0800
committerGitHub <noreply@github.com>2021-01-01 13:19:11 -0800
commitdfacac916fabe71ac2a2d1794504ba5b82e25f83 (patch)
tree8f4b63d80c184c6c0bb01f0ac009652e21e620b8 /src/codegen
parent5dfeb6cbc89d64f2a44eece41918e1c391c7c989 (diff)
parenta2ab2fb9b080e233e1de2cb1ef74bdbc9476acb9 (diff)
downloadzig-dfacac916fabe71ac2a2d1794504ba5b82e25f83.tar.gz
zig-dfacac916fabe71ac2a2d1794504ba5b82e25f83.zip
Merge pull request #7565 from joachimschmidt557/stage2-arm
stage2 ARM: add conditional branches
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/arm.zig66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/codegen/arm.zig b/src/codegen/arm.zig
index 33ff789648..978c653cb0 100644
--- a/src/codegen/arm.zig
+++ b/src/codegen/arm.zig
@@ -35,8 +35,74 @@ pub const Condition = enum(u4) {
le,
/// always
al,
+
+ /// Converts a std.math.CompareOperator into a condition flag,
+ /// i.e. returns the condition that is true iff the result of the
+ /// comparison is true. Assumes signed comparison
+ pub fn fromCompareOperatorSigned(op: std.math.CompareOperator) Condition {
+ return switch (op) {
+ .gte => .ge,
+ .gt => .gt,
+ .neq => .ne,
+ .lt => .lt,
+ .lte => .le,
+ .eq => .eq,
+ };
+ }
+
+ /// Converts a std.math.CompareOperator into a condition flag,
+ /// i.e. returns the condition that is true iff the result of the
+ /// comparison is true. Assumes unsigned comparison
+ pub fn fromCompareOperatorUnsigned(op: std.math.CompareOperator) Condition {
+ return switch (op) {
+ .gte => .cs,
+ .gt => .hi,
+ .neq => .ne,
+ .lt => .cc,
+ .lte => .ls,
+ .eq => .eq,
+ };
+ }
+
+ /// Returns the condition which is true iff the given condition is
+ /// false (if such a condition exists)
+ pub fn negate(cond: Condition) Condition {
+ return switch (cond) {
+ .eq => .ne,
+ .ne => .eq,
+ .cs => .cc,
+ .cc => .cs,
+ .mi => .pl,
+ .pl => .mi,
+ .vs => .vc,
+ .vc => .vs,
+ .hi => .ls,
+ .ls => .hi,
+ .ge => .lt,
+ .lt => .ge,
+ .gt => .le,
+ .le => .gt,
+ .al => unreachable,
+ };
+ }
};
+test "condition from CompareOperator" {
+ testing.expectEqual(@as(Condition, .eq), Condition.fromCompareOperatorSigned(.eq));
+ testing.expectEqual(@as(Condition, .eq), Condition.fromCompareOperatorUnsigned(.eq));
+
+ testing.expectEqual(@as(Condition, .gt), Condition.fromCompareOperatorSigned(.gt));
+ testing.expectEqual(@as(Condition, .hi), Condition.fromCompareOperatorUnsigned(.gt));
+
+ testing.expectEqual(@as(Condition, .le), Condition.fromCompareOperatorSigned(.lte));
+ testing.expectEqual(@as(Condition, .ls), Condition.fromCompareOperatorUnsigned(.lte));
+}
+
+test "negate condition" {
+ testing.expectEqual(@as(Condition, .eq), Condition.ne.negate());
+ testing.expectEqual(@as(Condition, .ne), Condition.eq.negate());
+}
+
/// Represents a register in the ARM instruction set architecture
pub const Register = enum(u5) {
r0,