aboutsummaryrefslogtreecommitdiff
path: root/src/arch/arm/bits.zig
diff options
context:
space:
mode:
authorjoachimschmidt557 <joachim.schmidt557@outlook.com>2022-02-24 22:18:21 +0100
committerjoachimschmidt557 <joachim.schmidt557@outlook.com>2022-02-26 12:59:57 +0100
commit8ef80cfaab2a74506d7b3a866dc066d9cd281f55 (patch)
tree5f96c3e02d299e29a9738c74ae429b9f967aac9d /src/arch/arm/bits.zig
parentdb82c1b9820449f2d1e6ef54dd32ec3ffd3c583f (diff)
downloadzig-8ef80cfaab2a74506d7b3a866dc066d9cd281f55.tar.gz
zig-8ef80cfaab2a74506d7b3a866dc066d9cd281f55.zip
stage2 ARM: implement truncate to ints with bits <= 32
Diffstat (limited to 'src/arch/arm/bits.zig')
-rw-r--r--src/arch/arm/bits.zig44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/arch/arm/bits.zig b/src/arch/arm/bits.zig
index 792bf0dc05..a8866ac5c9 100644
--- a/src/arch/arm/bits.zig
+++ b/src/arch/arm/bits.zig
@@ -1,5 +1,6 @@
const std = @import("std");
const DW = std.dwarf;
+const assert = std.debug.assert;
const testing = std.testing;
/// The condition field specifies the flags necessary for an
@@ -237,6 +238,17 @@ pub const Instruction = union(enum) {
fixed_3: u5 = 0b00010,
cond: u4,
},
+ bit_field_extract: packed struct {
+ rn: u4,
+ fixed_1: u3 = 0b101,
+ lsb: u5,
+ rd: u4,
+ widthm1: u5,
+ fixed_2: u1 = 0b1,
+ unsigned: u1,
+ fixed_3: u5 = 0b01111,
+ cond: u4,
+ },
single_data_transfer: packed struct {
offset: u12,
rd: u4,
@@ -576,6 +588,7 @@ pub const Instruction = union(enum) {
.multiply => |v| @bitCast(u32, v),
.multiply_long => |v| @bitCast(u32, v),
.integer_saturating_arithmetic => |v| @bitCast(u32, v),
+ .bit_field_extract => |v| @bitCast(u32, v),
.single_data_transfer => |v| @bitCast(u32, v),
.extra_load_store => |v| @bitCast(u32, v),
.block_data_transfer => |v| @bitCast(u32, v),
@@ -691,6 +704,27 @@ pub const Instruction = union(enum) {
};
}
+ fn bitFieldExtract(
+ unsigned: u1,
+ cond: Condition,
+ rd: Register,
+ rn: Register,
+ lsb: u5,
+ width: u6,
+ ) Instruction {
+ assert(width > 0 and width <= 32);
+ return Instruction{
+ .bit_field_extract = .{
+ .rn = rn.id(),
+ .lsb = lsb,
+ .rd = rd.id(),
+ .widthm1 = @intCast(u5, width - 1),
+ .unsigned = unsigned,
+ .cond = @enumToInt(cond),
+ },
+ };
+ }
+
fn singleDataTransfer(
cond: Condition,
rd: Register,
@@ -1044,6 +1078,16 @@ pub const Instruction = union(enum) {
return multiplyLong(cond, 1, 1, 1, rdhi, rdlo, rm, rn);
}
+ // Bit field extract
+
+ pub fn ubfx(cond: Condition, rd: Register, rn: Register, lsb: u5, width: u6) Instruction {
+ return bitFieldExtract(0b1, cond, rd, rn, lsb, width);
+ }
+
+ pub fn sbfx(cond: Condition, rd: Register, rn: Register, lsb: u5, width: u6) Instruction {
+ return bitFieldExtract(0b0, cond, rd, rn, lsb, width);
+ }
+
// Single data transfer
pub const OffsetArgs = struct {