diff options
| author | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2022-02-24 22:18:21 +0100 |
|---|---|---|
| committer | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2022-02-26 12:59:57 +0100 |
| commit | 8ef80cfaab2a74506d7b3a866dc066d9cd281f55 (patch) | |
| tree | 5f96c3e02d299e29a9738c74ae429b9f967aac9d /src/arch/arm/bits.zig | |
| parent | db82c1b9820449f2d1e6ef54dd32ec3ffd3c583f (diff) | |
| download | zig-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.zig | 44 |
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 { |
