| ... | @@ -6,11 +6,9 @@ pub const Operand = union(enum) { | ... | @@ -6,11 +6,9 @@ pub const Operand = union(enum) { |
| 6 | }; | 6 | }; |
| 7 | | 7 | |
| 8 | pub fn nextInstruction(as: *Assemble) !?Instruction { | 8 | pub fn nextInstruction(as: *Assemble) !?Instruction { |
| 9 | @setEvalBranchQuota(140_000); | | |
| 10 | comptime var ct_token_buf: [token_buf_len]u8 = undefined; | | |
| 11 | var token_buf: [token_buf_len]u8 = undefined; | | |
| 12 | const original_source = while (true) { | 9 | const original_source = while (true) { |
| 13 | const original_source = as.source; | 10 | const original_source = as.source; |
| | 11 | var token_buf: [token_buf_len]u8 = undefined; |
| 14 | const source_token = try as.nextToken(&token_buf, .{}); | 12 | const source_token = try as.nextToken(&token_buf, .{}); |
| 15 | switch (source_token.len) { | 13 | switch (source_token.len) { |
| 16 | 0 => return null, | 14 | 0 => return null, |
| ... | @@ -27,73 +25,9 @@ pub fn nextInstruction(as: *Assemble) !?Instruction { | ... | @@ -27,73 +25,9 @@ pub fn nextInstruction(as: *Assemble) !?Instruction { |
| 27 | \\========================= | 25 | \\========================= |
| 28 | \\ | 26 | \\ |
| 29 | , .{std.zig.fmtString(std.mem.span(original_source))}); | 27 | , .{std.zig.fmtString(std.mem.span(original_source))}); |
| 30 | inline for (instructions) |instruction| { | 28 | for (matchers) |matcher| { |
| 31 | next_pattern: { | 29 | as.source = original_source; |
| 32 | as.source = original_source; | 30 | if (try matcher(as)) |result| return result; |
| 33 | const Symbols = @TypeOf(instruction.symbols); | | |
| 34 | var symbols: Symbols: { | | |
| 35 | const symbols = @typeInfo(Symbols).@"struct".fields; | | |
| 36 | var symbol_fields: [symbols.len]std.builtin.Type.StructField = undefined; | | |
| 37 | for (&symbol_fields, symbols) |*symbol_field, symbol| { | | |
| 38 | const Storage = zonCast(SymbolSpec, @field(instruction.symbols, symbol.name), .{}).Storage(); | | |
| 39 | symbol_field.* = .{ | | |
| 40 | .name = symbol.name, | | |
| 41 | .type = Storage, | | |
| 42 | .default_value_ptr = null, | | |
| 43 | .is_comptime = false, | | |
| 44 | .alignment = @alignOf(Storage), | | |
| 45 | }; | | |
| 46 | } | | |
| 47 | break :Symbols @Type(.{ .@"struct" = .{ | | |
| 48 | .layout = .auto, | | |
| 49 | .fields = &symbol_fields, | | |
| 50 | .decls = &.{}, | | |
| 51 | .is_tuple = false, | | |
| 52 | } }); | | |
| 53 | } = undefined; | | |
| 54 | const Symbol = std.meta.FieldEnum(Symbols); | | |
| 55 | comptime var unused_symbols: std.enums.EnumSet(Symbol) = .initFull(); | | |
| 56 | comptime var pattern_as: Assemble = .{ .source = instruction.pattern, .operands = undefined }; | | |
| 57 | inline while (true) { | | |
| 58 | const pattern_token = comptime pattern_as.nextToken(&ct_token_buf, .{ .placeholders = true }) catch |err| | | |
| 59 | @compileError(@errorName(err) ++ " while parsing '" ++ instruction.pattern ++ "'"); | | |
| 60 | const source_token = try as.nextToken(&token_buf, .{ .operands = true }); | | |
| 61 | log.debug("\"{f}\" -> \"{f}\"", .{ | | |
| 62 | std.zig.fmtString(pattern_token), | | |
| 63 | std.zig.fmtString(source_token), | | |
| 64 | }); | | |
| 65 | if (pattern_token.len == 0) { | | |
| 66 | comptime var unused_symbol_it = unused_symbols.iterator(); | | |
| 67 | inline while (comptime unused_symbol_it.next()) |unused_symbol| | | |
| 68 | @compileError(@tagName(unused_symbol) ++ " unused while parsing '" ++ instruction.pattern ++ "'"); | | |
| 69 | switch (source_token.len) { | | |
| 70 | 0 => {}, | | |
| 71 | else => switch (source_token[0]) { | | |
| 72 | else => break :next_pattern, | | |
| 73 | '\n', ';' => {}, | | |
| 74 | }, | | |
| 75 | } | | |
| 76 | const encode = @field(Instruction, @tagName(instruction.encode[0])); | | |
| 77 | const Encode = @TypeOf(encode); | | |
| 78 | var args: std.meta.ArgsTuple(Encode) = undefined; | | |
| 79 | inline for (&args, @typeInfo(Encode).@"fn".params, 1..instruction.encode.len) |*arg, param, encode_index| | | |
| 80 | arg.* = zonCast(param.type.?, instruction.encode[encode_index], symbols); | | |
| 81 | return @call(.auto, encode, args); | | |
| 82 | } else if (pattern_token[0] == '<') { | | |
| 83 | const symbol_name = comptime pattern_token[1 .. std.mem.indexOfScalarPos(u8, pattern_token, 1, '|') orelse | | |
| 84 | pattern_token.len - 1]; | | |
| 85 | const symbol = @field(Symbol, symbol_name); | | |
| 86 | const symbol_ptr = &@field(symbols, symbol_name); | | |
| 87 | const symbol_value = zonCast(SymbolSpec, @field(instruction.symbols, symbol_name), .{}).parse(source_token) orelse break :next_pattern; | | |
| 88 | if (comptime unused_symbols.contains(symbol)) { | | |
| 89 | log.debug("{s} = {any}", .{ symbol_name, symbol_value }); | | |
| 90 | symbol_ptr.* = symbol_value; | | |
| 91 | comptime unused_symbols.remove(symbol); | | |
| 92 | } else if (symbol_ptr.* != symbol_value) break :next_pattern; | | |
| 93 | } else if (!toUpperEqlAssertUpper(source_token, pattern_token)) break :next_pattern; | | |
| 94 | } | | |
| 95 | } | | |
| 96 | log.debug("'{s}' not matched...", .{instruction.pattern}); | | |
| 97 | } | 31 | } |
| 98 | as.source = original_source; | 32 | as.source = original_source; |
| 99 | log.debug("Nothing matched!\n", .{}); | 33 | log.debug("Nothing matched!\n", .{}); |
| ... | @@ -106,6 +40,12 @@ fn zonCast(comptime Result: type, zon_value: anytype, symbols: anytype) Result { | ... | @@ -106,6 +40,12 @@ fn zonCast(comptime Result: type, zon_value: anytype, symbols: anytype) Result { |
| 106 | switch (@typeInfo(ZonValue)) { | 40 | switch (@typeInfo(ZonValue)) { |
| 107 | .void, .bool, .int, .float, .pointer, .comptime_float, .comptime_int, .@"enum" => return zon_value, | 41 | .void, .bool, .int, .float, .pointer, .comptime_float, .comptime_int, .@"enum" => return zon_value, |
| 108 | .@"struct" => |zon_struct| switch (@typeInfo(Result)) { | 42 | .@"struct" => |zon_struct| switch (@typeInfo(Result)) { |
| | 43 | .pointer => |result_pointer| { |
| | 44 | comptime assert(result_pointer.size == .slice and result_pointer.is_const); |
| | 45 | var elems: [zon_value.len]result_pointer.child = undefined; |
| | 46 | inline for (&elems, zon_value) |*elem, zon_elem| elem.* = zonCast(result_pointer.child, zon_elem, symbols); |
| | 47 | return &elems; |
| | 48 | }, |
| 109 | .@"struct" => |result_struct| { | 49 | .@"struct" => |result_struct| { |
| 110 | comptime var used_zon_fields = 0; | 50 | comptime var used_zon_fields = 0; |
| 111 | var result: Result = undefined; | 51 | var result: Result = undefined; |
| ... | @@ -158,6 +98,103 @@ fn zonCast(comptime Result: type, zon_value: anytype, symbols: anytype) Result { | ... | @@ -158,6 +98,103 @@ fn zonCast(comptime Result: type, zon_value: anytype, symbols: anytype) Result { |
| 158 | } | 98 | } |
| 159 | } | 99 | } |
| 160 | | 100 | |
| | 101 | const matchers = matchers: { |
| | 102 | const instructions = @import("instructions.zon"); |
| | 103 | var mut_matchers: [instructions.len]*const fn (as: *Assemble) error{InvalidSyntax}!?Instruction = undefined; |
| | 104 | for (instructions, &mut_matchers) |instruction, *matcher| matcher.* = struct { |
| | 105 | fn match(as: *Assemble) !?Instruction { |
| | 106 | comptime for (@typeInfo(@TypeOf(instruction)).@"struct".fields) |field| { |
| | 107 | if (std.mem.eql(u8, field.name, "requires")) continue; |
| | 108 | if (std.mem.eql(u8, field.name, "pattern")) continue; |
| | 109 | if (std.mem.eql(u8, field.name, "symbols")) continue; |
| | 110 | if (std.mem.eql(u8, field.name, "encode")) continue; |
| | 111 | @compileError("unexpected field '" ++ field.name ++ "'"); |
| | 112 | }; |
| | 113 | if (@hasField(@TypeOf(instruction), "requires")) _ = zonCast( |
| | 114 | []const std.Target.aarch64.Feature, |
| | 115 | instruction.requires, |
| | 116 | .{}, |
| | 117 | ); |
| | 118 | var symbols: Symbols: { |
| | 119 | const symbols = @typeInfo(@TypeOf(instruction.symbols)).@"struct".fields; |
| | 120 | var symbol_fields: [symbols.len]std.builtin.Type.StructField = undefined; |
| | 121 | for (&symbol_fields, symbols) |*symbol_field, symbol| { |
| | 122 | const Storage = zonCast(SymbolSpec, @field(instruction.symbols, symbol.name), .{}).Storage(); |
| | 123 | symbol_field.* = .{ |
| | 124 | .name = symbol.name, |
| | 125 | .type = Storage, |
| | 126 | .default_value_ptr = null, |
| | 127 | .is_comptime = false, |
| | 128 | .alignment = @alignOf(Storage), |
| | 129 | }; |
| | 130 | } |
| | 131 | break :Symbols @Type(.{ .@"struct" = .{ |
| | 132 | .layout = .auto, |
| | 133 | .fields = &symbol_fields, |
| | 134 | .decls = &.{}, |
| | 135 | .is_tuple = false, |
| | 136 | } }); |
| | 137 | } = undefined; |
| | 138 | const Symbol = std.meta.FieldEnum(@TypeOf(instruction.symbols)); |
| | 139 | comptime var unused_symbols: std.enums.EnumSet(Symbol) = .initFull(); |
| | 140 | comptime var pattern_as: Assemble = .{ .source = instruction.pattern, .operands = undefined }; |
| | 141 | inline while (true) { |
| | 142 | comptime var ct_token_buf: [token_buf_len]u8 = undefined; |
| | 143 | var token_buf: [token_buf_len]u8 = undefined; |
| | 144 | const pattern_token = comptime pattern_as.nextToken(&ct_token_buf, .{ .placeholders = true }) catch |err| |
| | 145 | @compileError(@errorName(err) ++ " while parsing '" ++ instruction.pattern ++ "'"); |
| | 146 | const source_token = try as.nextToken(&token_buf, .{ .operands = true }); |
| | 147 | log.debug("\"{f}\" -> \"{f}\"", .{ |
| | 148 | std.zig.fmtString(pattern_token), |
| | 149 | std.zig.fmtString(source_token), |
| | 150 | }); |
| | 151 | if (pattern_token.len == 0) { |
| | 152 | comptime var unused_symbol_it = unused_symbols.iterator(); |
| | 153 | inline while (comptime unused_symbol_it.next()) |unused_symbol| |
| | 154 | @compileError(@tagName(unused_symbol) ++ " unused while parsing '" ++ instruction.pattern ++ "'"); |
| | 155 | switch (source_token.len) { |
| | 156 | 0 => {}, |
| | 157 | else => switch (source_token[0]) { |
| | 158 | else => { |
| | 159 | log.debug("'{s}' not matched...", .{instruction.pattern}); |
| | 160 | return null; |
| | 161 | }, |
| | 162 | '\n', ';' => {}, |
| | 163 | }, |
| | 164 | } |
| | 165 | const encode = @field(Instruction, @tagName(instruction.encode[0])); |
| | 166 | const Encode = @TypeOf(encode); |
| | 167 | var args: std.meta.ArgsTuple(Encode) = undefined; |
| | 168 | inline for (&args, @typeInfo(Encode).@"fn".params, 1..instruction.encode.len) |*arg, param, encode_index| |
| | 169 | arg.* = zonCast(param.type.?, instruction.encode[encode_index], symbols); |
| | 170 | return @call(.auto, encode, args); |
| | 171 | } else if (pattern_token[0] == '<') { |
| | 172 | const symbol_name = comptime pattern_token[1 .. std.mem.indexOfScalarPos(u8, pattern_token, 1, '|') orelse |
| | 173 | pattern_token.len - 1]; |
| | 174 | const symbol = @field(Symbol, symbol_name); |
| | 175 | const symbol_ptr = &@field(symbols, symbol_name); |
| | 176 | const symbol_value = zonCast(SymbolSpec, @field(instruction.symbols, symbol_name), .{}).parse(source_token) orelse { |
| | 177 | log.debug("'{s}' not matched...", .{instruction.pattern}); |
| | 178 | return null; |
| | 179 | }; |
| | 180 | if (comptime unused_symbols.contains(symbol)) { |
| | 181 | log.debug("{s} = {any}", .{ symbol_name, symbol_value }); |
| | 182 | symbol_ptr.* = symbol_value; |
| | 183 | comptime unused_symbols.remove(symbol); |
| | 184 | } else if (symbol_ptr.* != symbol_value) { |
| | 185 | log.debug("'{s}' not matched...", .{instruction.pattern}); |
| | 186 | return null; |
| | 187 | } |
| | 188 | } else if (!toUpperEqlAssertUpper(source_token, pattern_token)) { |
| | 189 | log.debug("'{s}' not matched...", .{instruction.pattern}); |
| | 190 | return null; |
| | 191 | } |
| | 192 | } |
| | 193 | } |
| | 194 | }.match; |
| | 195 | break :matchers mut_matchers; |
| | 196 | }; |
| | 197 | |
| 161 | fn toUpperEqlAssertUpper(lhs: []const u8, rhs: []const u8) bool { | 198 | fn toUpperEqlAssertUpper(lhs: []const u8, rhs: []const u8) bool { |
| 162 | if (lhs.len != rhs.len) return false; | 199 | if (lhs.len != rhs.len) return false; |
| 163 | for (lhs, rhs) |l, r| { | 200 | for (lhs, rhs) |l, r| { |
| ... | @@ -281,9 +318,10 @@ const SymbolSpec = union(enum) { | ... | @@ -281,9 +318,10 @@ const SymbolSpec = union(enum) { |
| 281 | multiple_of: ?comptime_int = null, | 318 | multiple_of: ?comptime_int = null, |
| 282 | min_valid: ?comptime_int = null, | 319 | min_valid: ?comptime_int = null, |
| 283 | max_valid: ?comptime_int = null, | 320 | max_valid: ?comptime_int = null, |
| | 321 | adjust: enum { none, neg_wrap, dec } = .none, |
| 284 | }, | 322 | }, |
| 285 | fimm: struct { only_valid: ?f16 = null }, | 323 | fimm: struct { only_valid: ?f16 = null }, |
| 286 | extend: struct { size: aarch64.encoding.Register.GeneralSize }, | 324 | extend: struct { size: ?aarch64.encoding.Register.GeneralSize = null }, |
| 287 | shift: struct { allow_ror: bool = true }, | 325 | shift: struct { allow_ror: bool = true }, |
| 288 | barrier: struct { only_sy: bool = false }, | 326 | barrier: struct { only_sy: bool = false }, |
| 289 | | 327 | |
| ... | @@ -293,7 +331,7 @@ const SymbolSpec = union(enum) { | ... | @@ -293,7 +331,7 @@ const SymbolSpec = union(enum) { |
| 293 | .reg => aarch64.encoding.Register, | 331 | .reg => aarch64.encoding.Register, |
| 294 | .arrangement => aarch64.encoding.Register.Arrangement, | 332 | .arrangement => aarch64.encoding.Register.Arrangement, |
| 295 | .systemreg => aarch64.encoding.Register.System, | 333 | .systemreg => aarch64.encoding.Register.System, |
| 296 | .imm => |imm| @Type(.{ .int = imm.type }), | 334 | .imm => |imm_spec| @Type(.{ .int = imm_spec.type }), |
| 297 | .fimm => f16, | 335 | .fimm => f16, |
| 298 | .extend => Instruction.DataProcessingRegister.AddSubtractExtendedRegister.Option, | 336 | .extend => Instruction.DataProcessingRegister.AddSubtractExtendedRegister.Option, |
| 299 | .shift => Instruction.DataProcessingRegister.Shift.Op, | 337 | .shift => Instruction.DataProcessingRegister.Shift.Op, |
| ... | @@ -372,7 +410,13 @@ const SymbolSpec = union(enum) { | ... | @@ -372,7 +410,13 @@ const SymbolSpec = union(enum) { |
| 372 | return systemreg; | 410 | return systemreg; |
| 373 | }, | 411 | }, |
| 374 | .imm => |imm_spec| { | 412 | .imm => |imm_spec| { |
| 375 | const imm = std.fmt.parseInt(Result, token, 0) catch { | 413 | const imm = std.fmt.parseInt(@Type(.{ .int = .{ |
| | 414 | .signedness = imm_spec.type.signedness, |
| | 415 | .bits = switch (imm_spec.adjust) { |
| | 416 | .none, .neg_wrap => imm_spec.type.bits, |
| | 417 | .dec => imm_spec.type.bits + 1, |
| | 418 | }, |
| | 419 | } }), token, 0) catch { |
| 376 | log.debug("invalid immediate: \"{f}\"", .{std.zig.fmtString(token)}); | 420 | log.debug("invalid immediate: \"{f}\"", .{std.zig.fmtString(token)}); |
| 377 | return null; | 421 | return null; |
| 378 | }; | 422 | }; |
| ... | @@ -388,7 +432,14 @@ const SymbolSpec = union(enum) { | ... | @@ -388,7 +432,14 @@ const SymbolSpec = union(enum) { |
| 388 | log.debug("out of range immediate: \"{f}\"", .{std.zig.fmtString(token)}); | 432 | log.debug("out of range immediate: \"{f}\"", .{std.zig.fmtString(token)}); |
| 389 | return null; | 433 | return null; |
| 390 | }; | 434 | }; |
| 391 | return imm; | 435 | return switch (imm_spec.adjust) { |
| | 436 | .none => imm, |
| | 437 | .neg_wrap => -%imm, |
| | 438 | .dec => std.math.cast(Result, imm - 1) orelse { |
| | 439 | log.debug("out of range immediate: \"{f}\"", .{std.zig.fmtString(token)}); |
| | 440 | return null; |
| | 441 | }, |
| | 442 | }; |
| 392 | }, | 443 | }, |
| 393 | .fimm => |fimm_spec| { | 444 | .fimm => |fimm_spec| { |
| 394 | const full_fimm = std.fmt.parseFloat(f128, token) catch { | 445 | const full_fimm = std.fmt.parseFloat(f128, token) catch { |
| ... | @@ -433,10 +484,10 @@ const SymbolSpec = union(enum) { | ... | @@ -433,10 +484,10 @@ const SymbolSpec = union(enum) { |
| 433 | log.debug("invalid extend: \"{f}\"", .{std.zig.fmtString(token)}); | 484 | log.debug("invalid extend: \"{f}\"", .{std.zig.fmtString(token)}); |
| 434 | return null; | 485 | return null; |
| 435 | }; | 486 | }; |
| 436 | if (extend.sf() != extend_spec.size) { | 487 | if (extend_spec.size) |size| if (extend.sf() != size) { |
| 437 | log.debug("invalid extend: \"{f}\"", .{std.zig.fmtString(token)}); | 488 | log.debug("invalid extend: \"{f}\"", .{std.zig.fmtString(token)}); |
| 438 | return null; | 489 | return null; |
| 439 | } | 490 | }; |
| 440 | return extend; | 491 | return extend; |
| 441 | }, | 492 | }, |
| 442 | .shift => |shift_spec| { | 493 | .shift => |shift_spec| { |
| ... | @@ -488,6 +539,16 @@ const SymbolSpec = union(enum) { | ... | @@ -488,6 +539,16 @@ const SymbolSpec = union(enum) { |
| 488 | test "add sub" { | 539 | test "add sub" { |
| 489 | var as: Assemble = .{ | 540 | var as: Assemble = .{ |
| 490 | .source = | 541 | .source = |
| | 542 | \\ adc w0, w0, w1 |
| | 543 | \\ adc w2, w3, w4 |
| | 544 | \\ adc w5, w5, wzr |
| | 545 | \\ adc w6, w7, wzr |
| | 546 | \\ |
| | 547 | \\ adcs w0, w0, w1 |
| | 548 | \\ adcs w2, w3, w4 |
| | 549 | \\ adcs w5, w5, wzr |
| | 550 | \\ adcs w6, w7, wzr |
| | 551 | \\ |
| 491 | \\ add w0, w0, w1 | 552 | \\ add w0, w0, w1 |
| 492 | \\ add w2, w3, w4 | 553 | \\ add w2, w3, w4 |
| 493 | \\ add wsp, w5, w6 | 554 | \\ add wsp, w5, w6 |
| ... | @@ -513,13 +574,13 @@ test "add sub" { | ... | @@ -513,13 +574,13 @@ test "add sub" { |
| 513 | \\ add w0, w0, w1 | 574 | \\ add w0, w0, w1 |
| 514 | \\ add w2, w3, w4, uxtb #0 | 575 | \\ add w2, w3, w4, uxtb #0 |
| 515 | \\ add wsp, w5, w6, uxth #1 | 576 | \\ add wsp, w5, w6, uxth #1 |
| 516 | \\ add w7, wsp, w8, uxtw #0 | 577 | \\ add w7, wsp, w8, uxtw #2 |
| 517 | \\ add wsp, wsp, w9, uxtw #2 | 578 | \\ add wsp, wsp, w9, uxtx #0 |
| 518 | \\ add w10, w10, wzr, uxtw #3 | 579 | \\ add w10, w10, wzr, uxtx #3 |
| 519 | \\ add w11, w12, wzr, sxtb #4 | 580 | \\ add w11, w12, wzr, sxtb #4 |
| 520 | \\ add wsp, w13, wzr, sxth #0 | 581 | \\ add wsp, w13, wzr, sxth #0 |
| 521 | \\ add w14, wsp, wzr, sxtw #1 | 582 | \\ add w14, wsp, wzr, sxtw #1 |
| 522 | \\ add wsp, wsp, wzr, sxtw #2 | 583 | \\ add wsp, wsp, wzr, sxtx #2 |
| 523 | \\ | 584 | \\ |
| 524 | \\ add x0, x0, x1 | 585 | \\ add x0, x0, x1 |
| 525 | \\ add x2, x3, w4, uxtb #0 | 586 | \\ add x2, x3, w4, uxtb #0 |
| ... | @@ -582,6 +643,125 @@ test "add sub" { | ... | @@ -582,6 +643,125 @@ test "add sub" { |
| 582 | \\ add xzr, xzr, x13, asr #0x1F | 643 | \\ add xzr, xzr, x13, asr #0x1F |
| 583 | \\ add xzr, xzr, xzr, asr #0x3f | 644 | \\ add xzr, xzr, xzr, asr #0x3f |
| 584 | \\ | 645 | \\ |
| | 646 | \\ addg x0, sp, #0, #0xf |
| | 647 | \\ addg sp, x1, #0x3f0, #0 |
| | 648 | \\ |
| | 649 | \\ adds w0, w0, w1 |
| | 650 | \\ adds w2, w3, w4 |
| | 651 | \\ adds w5, w5, w6 |
| | 652 | \\ adds w7, wsp, w8 |
| | 653 | \\ adds w9, wsp, w9 |
| | 654 | \\ adds w10, w10, wzr |
| | 655 | \\ adds w11, w12, wzr |
| | 656 | \\ adds wzr, w13, wzr |
| | 657 | \\ adds w14, wsp, wzr |
| | 658 | \\ adds wzr, wsp, wzr |
| | 659 | \\ |
| | 660 | \\ adds x0, x0, x1 |
| | 661 | \\ adds x2, x3, x4 |
| | 662 | \\ adds x5, x5, x6 |
| | 663 | \\ adds x7, sp, x8 |
| | 664 | \\ adds x9, sp, x9 |
| | 665 | \\ adds x10, x10, xzr |
| | 666 | \\ adds x11, x12, xzr |
| | 667 | \\ adds xzr, x13, xzr |
| | 668 | \\ adds x14, sp, xzr |
| | 669 | \\ adds xzr, sp, xzr |
| | 670 | \\ |
| | 671 | \\ adds w0, w0, w1 |
| | 672 | \\ adds w2, w3, w4, uxtb #0 |
| | 673 | \\ adds wzr, w5, w6, uxth #1 |
| | 674 | \\ adds w7, wsp, w8, uxtw #2 |
| | 675 | \\ adds w9, wsp, w9, uxtx #0 |
| | 676 | \\ adds w10, w10, wzr, uxtx #3 |
| | 677 | \\ adds w11, w12, wzr, sxtb #4 |
| | 678 | \\ adds wzr, w13, wzr, sxth #0 |
| | 679 | \\ adds w14, wsp, wzr, sxtw #1 |
| | 680 | \\ adds wzr, wsp, wzr, sxtx #2 |
| | 681 | \\ |
| | 682 | \\ adds x0, x0, x1 |
| | 683 | \\ adds x2, x3, w4, uxtb #0 |
| | 684 | \\ adds xzr, x5, w6, uxth #1 |
| | 685 | \\ adds x7, sp, w8, uxtw #2 |
| | 686 | \\ adds xzr, sp, x9, uxtx #0 |
| | 687 | \\ adds x10, x10, xzr, uxtx #3 |
| | 688 | \\ adds x11, x12, wzr, sxtb #4 |
| | 689 | \\ adds xzr, x13, wzr, sxth #0 |
| | 690 | \\ adds x14, sp, wzr, sxtw #1 |
| | 691 | \\ adds xzr, sp, xzr, sxtx #2 |
| | 692 | \\ |
| | 693 | \\ adds w0, w0, #0 |
| | 694 | \\ adds w0, w1, #1, lsl #0 |
| | 695 | \\ adds wzr, w2, #2, lsl #12 |
| | 696 | \\ adds w3, wsp, #3, lsl #0 |
| | 697 | \\ adds wzr, wsp, #4095, lsl #12 |
| | 698 | \\ adds w0, w1, #0 |
| | 699 | \\ adds w2, w3, #0, lsl #0 |
| | 700 | \\ adds w4, wsp, #0 |
| | 701 | \\ adds w5, wsp, #0, lsl #0 |
| | 702 | \\ adds wzr, w6, #0 |
| | 703 | \\ adds wzr, w7, #0, lsl #0 |
| | 704 | \\ adds wzr, wsp, #0 |
| | 705 | \\ adds wzr, wsp, #0, lsl #0 |
| | 706 | \\ |
| | 707 | \\ adds x0, x0, #0 |
| | 708 | \\ adds x0, x1, #1, lsl #0 |
| | 709 | \\ adds xzr, x2, #2, lsl #12 |
| | 710 | \\ adds x3, sp, #3, lsl #0 |
| | 711 | \\ adds xzr, sp, #4095, lsl #12 |
| | 712 | \\ adds x0, x1, #0 |
| | 713 | \\ adds x2, x3, #0, lsl #0 |
| | 714 | \\ adds x4, sp, #0 |
| | 715 | \\ adds x5, sp, #0, lsl #0 |
| | 716 | \\ adds xzr, x6, #0 |
| | 717 | \\ adds xzr, x7, #0, lsl #0 |
| | 718 | \\ adds xzr, sp, #0 |
| | 719 | \\ adds xzr, sp, #0, lsl #0 |
| | 720 | \\ |
| | 721 | \\ adds w0, w0, w0 |
| | 722 | \\ adds w1, w1, w2, lsl #0 |
| | 723 | \\ adds w3, w4, w5, lsl #1 |
| | 724 | \\ adds w6, w6, wzr, lsl #31 |
| | 725 | \\ adds w7, wzr, w8, lsr #0 |
| | 726 | \\ adds w9, wzr, wzr, lsr #30 |
| | 727 | \\ adds wzr, w10, w11, lsr #31 |
| | 728 | \\ adds wzr, w12, wzr, asr #0x0 |
| | 729 | \\ adds wzr, wzr, w13, asr #0x10 |
| | 730 | \\ adds wzr, wzr, wzr, asr #0x1f |
| | 731 | \\ |
| | 732 | \\ adds x0, x0, x0 |
| | 733 | \\ adds x1, x1, x2, lsl #0 |
| | 734 | \\ adds x3, x4, x5, lsl #1 |
| | 735 | \\ adds x6, x6, xzr, lsl #63 |
| | 736 | \\ adds x7, xzr, x8, lsr #0 |
| | 737 | \\ adds x9, xzr, xzr, lsr #62 |
| | 738 | \\ adds xzr, x10, x11, lsr #63 |
| | 739 | \\ adds xzr, x12, xzr, asr #0x0 |
| | 740 | \\ adds xzr, xzr, x13, asr #0x1F |
| | 741 | \\ adds xzr, xzr, xzr, asr #0x3f |
| | 742 | \\ |
| | 743 | \\ neg w0, w0 |
| | 744 | \\ neg w1, w2, lsl #0 |
| | 745 | \\ neg w3, wzr, lsl #7 |
| | 746 | \\ neg wzr, w4, lsr #14 |
| | 747 | \\ neg wzr, wzr, asr #21 |
| | 748 | \\ |
| | 749 | \\ neg x0, x0 |
| | 750 | \\ neg x1, x2, lsl #0 |
| | 751 | \\ neg x3, xzr, lsl #11 |
| | 752 | \\ neg xzr, x4, lsr #22 |
| | 753 | \\ neg xzr, xzr, asr #33 |
| | 754 | \\ |
| | 755 | \\ sbc w0, w0, w1 |
| | 756 | \\ sbc w2, w3, w4 |
| | 757 | \\ sbc w5, w5, wzr |
| | 758 | \\ sbc w6, w7, wzr |
| | 759 | \\ |
| | 760 | \\ sbcs w0, w0, w1 |
| | 761 | \\ sbcs w2, w3, w4 |
| | 762 | \\ sbcs w5, w5, wzr |
| | 763 | \\ sbcs w6, w7, wzr |
| | 764 | \\ |
| 585 | \\ sub w0, w0, w1 | 765 | \\ sub w0, w0, w1 |
| 586 | \\ sub w2, w3, w4 | 766 | \\ sub w2, w3, w4 |
| 587 | \\ sub wsp, w5, w6 | 767 | \\ sub wsp, w5, w6 |
| ... | @@ -607,13 +787,13 @@ test "add sub" { | ... | @@ -607,13 +787,13 @@ test "add sub" { |
| 607 | \\ sub w0, w0, w1 | 787 | \\ sub w0, w0, w1 |
| 608 | \\ sub w2, w3, w4, uxtb #0 | 788 | \\ sub w2, w3, w4, uxtb #0 |
| 609 | \\ sub wsp, w5, w6, uxth #1 | 789 | \\ sub wsp, w5, w6, uxth #1 |
| 610 | \\ sub w7, wsp, w8, uxtw #0 | 790 | \\ sub w7, wsp, w8, uxtw #2 |
| 611 | \\ sub wsp, wsp, w9, uxtw #2 | 791 | \\ sub wsp, wsp, w9, uxtx #0 |
| 612 | \\ sub w10, w10, wzr, uxtw #3 | 792 | \\ sub w10, w10, wzr, uxtx #3 |
| 613 | \\ sub w11, w12, wzr, sxtb #4 | 793 | \\ sub w11, w12, wzr, sxtb #4 |
| 614 | \\ sub wsp, w13, wzr, sxth #0 | 794 | \\ sub wsp, w13, wzr, sxth #0 |
| 615 | \\ sub w14, wsp, wzr, sxtw #1 | 795 | \\ sub w14, wsp, wzr, sxtw #1 |
| 616 | \\ sub wsp, wsp, wzr, sxtw #2 | 796 | \\ sub wsp, wsp, wzr, sxtx #2 |
| 617 | \\ | 797 | \\ |
| 618 | \\ sub x0, x0, x1 | 798 | \\ sub x0, x0, x1 |
| 619 | \\ sub x2, x3, w4, uxtb #0 | 799 | \\ sub x2, x3, w4, uxtb #0 |
| ... | @@ -676,21 +856,116 @@ test "add sub" { | ... | @@ -676,21 +856,116 @@ test "add sub" { |
| 676 | \\ sub xzr, xzr, x13, asr #0x1F | 856 | \\ sub xzr, xzr, x13, asr #0x1F |
| 677 | \\ sub xzr, xzr, xzr, asr #0x3f | 857 | \\ sub xzr, xzr, xzr, asr #0x3f |
| 678 | \\ | 858 | \\ |
| 679 | \\ neg w0, w0 | 859 | \\ subg x0, sp, #0, #0xf |
| 680 | \\ neg w1, w2, lsl #0 | 860 | \\ subg sp, x1, #0x3f0, #0 |
| 681 | \\ neg w3, wzr, lsl #7 | 861 | \\ |
| 682 | \\ neg wzr, w4, lsr #14 | 862 | \\ subs w0, w0, w1 |
| 683 | \\ neg wzr, wzr, asr #21 | 863 | \\ subs w2, w3, w4 |
| 684 | \\ | 864 | \\ subs w5, w5, w6 |
| 685 | \\ neg x0, x0 | 865 | \\ subs w7, wsp, w8 |
| 686 | \\ neg x1, x2, lsl #0 | 866 | \\ subs w9, wsp, w9 |
| 687 | \\ neg x3, xzr, lsl #11 | 867 | \\ subs w10, w10, wzr |
| 688 | \\ neg xzr, x4, lsr #22 | 868 | \\ subs w11, w12, wzr |
| 689 | \\ neg xzr, xzr, asr #33 | 869 | \\ subs wzr, w13, wzr |
| | 870 | \\ subs w14, wsp, wzr |
| | 871 | \\ subs wzr, wsp, wzr |
| | 872 | \\ |
| | 873 | \\ subs x0, x0, x1 |
| | 874 | \\ subs x2, x3, x4 |
| | 875 | \\ subs x5, x5, x6 |
| | 876 | \\ subs x7, sp, x8 |
| | 877 | \\ subs x9, sp, x9 |
| | 878 | \\ subs x10, x10, xzr |
| | 879 | \\ subs x11, x12, xzr |
| | 880 | \\ subs xzr, x13, xzr |
| | 881 | \\ subs x14, sp, xzr |
| | 882 | \\ subs xzr, sp, xzr |
| | 883 | \\ |
| | 884 | \\ subs w0, w0, w1 |
| | 885 | \\ subs w2, w3, w4, uxtb #0 |
| | 886 | \\ subs wzr, w5, w6, uxth #1 |
| | 887 | \\ subs w7, wsp, w8, uxtw #2 |
| | 888 | \\ subs w9, wsp, w9, uxtx #0 |
| | 889 | \\ subs w10, w10, wzr, uxtx #3 |
| | 890 | \\ subs w11, w12, wzr, sxtb #4 |
| | 891 | \\ subs wzr, w13, wzr, sxth #0 |
| | 892 | \\ subs w14, wsp, wzr, sxtw #1 |
| | 893 | \\ subs wzr, wsp, wzr, sxtx #2 |
| | 894 | \\ |
| | 895 | \\ subs x0, x0, x1 |
| | 896 | \\ subs x2, x3, w4, uxtb #0 |
| | 897 | \\ subs xzr, x5, w6, uxth #1 |
| | 898 | \\ subs x7, sp, w8, uxtw #2 |
| | 899 | \\ subs xzr, sp, x9, uxtx #0 |
| | 900 | \\ subs x10, x10, xzr, uxtx #3 |
| | 901 | \\ subs x11, x12, wzr, sxtb #4 |
| | 902 | \\ subs xzr, x13, wzr, sxth #0 |
| | 903 | \\ subs x14, sp, wzr, sxtw #1 |
| | 904 | \\ subs xzr, sp, xzr, sxtx #2 |
| | 905 | \\ |
| | 906 | \\ subs w0, w0, #0 |
| | 907 | \\ subs w0, w1, #1, lsl #0 |
| | 908 | \\ subs wzr, w2, #2, lsl #12 |
| | 909 | \\ subs w3, wsp, #3, lsl #0 |
| | 910 | \\ subs wzr, wsp, #4095, lsl #12 |
| | 911 | \\ subs w0, w1, #0 |
| | 912 | \\ subs w2, w3, #0, lsl #0 |
| | 913 | \\ subs w4, wsp, #0 |
| | 914 | \\ subs w5, wsp, #0, lsl #0 |
| | 915 | \\ subs wzr, w6, #0 |
| | 916 | \\ subs wzr, w7, #0, lsl #0 |
| | 917 | \\ subs wzr, wsp, #0 |
| | 918 | \\ subs wzr, wsp, #0, lsl #0 |
| | 919 | \\ |
| | 920 | \\ subs x0, x0, #0 |
| | 921 | \\ subs x0, x1, #1, lsl #0 |
| | 922 | \\ subs xzr, x2, #2, lsl #12 |
| | 923 | \\ subs x3, sp, #3, lsl #0 |
| | 924 | \\ subs xzr, sp, #4095, lsl #12 |
| | 925 | \\ subs x0, x1, #0 |
| | 926 | \\ subs x2, x3, #0, lsl #0 |
| | 927 | \\ subs x4, sp, #0 |
| | 928 | \\ subs x5, sp, #0, lsl #0 |
| | 929 | \\ subs xzr, x6, #0 |
| | 930 | \\ subs xzr, x7, #0, lsl #0 |
| | 931 | \\ subs xzr, sp, #0 |
| | 932 | \\ subs xzr, sp, #0, lsl #0 |
| | 933 | \\ |
| | 934 | \\ subs w0, w0, w0 |
| | 935 | \\ subs w1, w1, w2, lsl #0 |
| | 936 | \\ subs w3, w4, w5, lsl #1 |
| | 937 | \\ subs w6, w6, wzr, lsl #31 |
| | 938 | \\ subs w7, wzr, w8, lsr #0 |
| | 939 | \\ subs w9, wzr, wzr, lsr #30 |
| | 940 | \\ subs wzr, w10, w11, lsr #31 |
| | 941 | \\ subs wzr, w12, wzr, asr #0x0 |
| | 942 | \\ subs wzr, wzr, w13, asr #0x10 |
| | 943 | \\ subs wzr, wzr, wzr, asr #0x1f |
| | 944 | \\ |
| | 945 | \\ subs x0, x0, x0 |
| | 946 | \\ subs x1, x1, x2, lsl #0 |
| | 947 | \\ subs x3, x4, x5, lsl #1 |
| | 948 | \\ subs x6, x6, xzr, lsl #63 |
| | 949 | \\ subs x7, xzr, x8, lsr #0 |
| | 950 | \\ subs x9, xzr, xzr, lsr #62 |
| | 951 | \\ subs xzr, x10, x11, lsr #63 |
| | 952 | \\ subs xzr, x12, xzr, asr #0x0 |
| | 953 | \\ subs xzr, xzr, x13, asr #0x1F |
| | 954 | \\ subs xzr, xzr, xzr, asr #0x3f |
| 690 | , | 955 | , |
| 691 | .operands = .empty, | 956 | .operands = .empty, |
| 692 | }; | 957 | }; |
| 693 | | 958 | |
| | 959 | try std.testing.expectFmt("adc w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| | 960 | try std.testing.expectFmt("adc w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); |
| | 961 | try std.testing.expectFmt("adc w5, w5, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 962 | try std.testing.expectFmt("adc w6, w7, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 963 | |
| | 964 | try std.testing.expectFmt("adcs w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| | 965 | try std.testing.expectFmt("adcs w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); |
| | 966 | try std.testing.expectFmt("adcs w5, w5, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 967 | try std.testing.expectFmt("adcs w6, w7, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 968 | |
| 694 | try std.testing.expectFmt("add w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); | 969 | try std.testing.expectFmt("add w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| 695 | try std.testing.expectFmt("add w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); | 970 | try std.testing.expectFmt("add w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); |
| 696 | try std.testing.expectFmt("add wsp, w5, w6", "{f}", .{(try as.nextInstruction()).?}); | 971 | try std.testing.expectFmt("add wsp, w5, w6", "{f}", .{(try as.nextInstruction()).?}); |
| ... | @@ -714,24 +989,24 @@ test "add sub" { | ... | @@ -714,24 +989,24 @@ test "add sub" { |
| 714 | try std.testing.expectFmt("add sp, sp, xzr", "{f}", .{(try as.nextInstruction()).?}); | 989 | try std.testing.expectFmt("add sp, sp, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| 715 | | 990 | |
| 716 | try std.testing.expectFmt("add w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); | 991 | try std.testing.expectFmt("add w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| 717 | try std.testing.expectFmt("add w2, w3, w4, uxtb #0", "{f}", .{(try as.nextInstruction()).?}); | 992 | try std.testing.expectFmt("add w2, w3, w4, uxtb", "{f}", .{(try as.nextInstruction()).?}); |
| 718 | try std.testing.expectFmt("add wsp, w5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); | 993 | try std.testing.expectFmt("add wsp, w5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); |
| 719 | try std.testing.expectFmt("add w7, wsp, w8", "{f}", .{(try as.nextInstruction()).?}); | 994 | try std.testing.expectFmt("add w7, wsp, w8, lsl #2", "{f}", .{(try as.nextInstruction()).?}); |
| 720 | try std.testing.expectFmt("add wsp, wsp, w9, uxtw #2", "{f}", .{(try as.nextInstruction()).?}); | 995 | try std.testing.expectFmt("add wsp, wsp, w9, uxtx", "{f}", .{(try as.nextInstruction()).?}); |
| 721 | try std.testing.expectFmt("add w10, w10, wzr, uxtw #3", "{f}", .{(try as.nextInstruction()).?}); | 996 | try std.testing.expectFmt("add w10, w10, wzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); |
| 722 | try std.testing.expectFmt("add w11, w12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); | 997 | try std.testing.expectFmt("add w11, w12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); |
| 723 | try std.testing.expectFmt("add wsp, w13, wzr, sxth #0", "{f}", .{(try as.nextInstruction()).?}); | 998 | try std.testing.expectFmt("add wsp, w13, wzr, sxth", "{f}", .{(try as.nextInstruction()).?}); |
| 724 | try std.testing.expectFmt("add w14, wsp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); | 999 | try std.testing.expectFmt("add w14, wsp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); |
| 725 | try std.testing.expectFmt("add wsp, wsp, wzr, sxtw #2", "{f}", .{(try as.nextInstruction()).?}); | 1000 | try std.testing.expectFmt("add wsp, wsp, wzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); |
| 726 | | 1001 | |
| 727 | try std.testing.expectFmt("add x0, x0, x1", "{f}", .{(try as.nextInstruction()).?}); | 1002 | try std.testing.expectFmt("add x0, x0, x1", "{f}", .{(try as.nextInstruction()).?}); |
| 728 | try std.testing.expectFmt("add x2, x3, w4, uxtb #0", "{f}", .{(try as.nextInstruction()).?}); | 1003 | try std.testing.expectFmt("add x2, x3, w4, uxtb", "{f}", .{(try as.nextInstruction()).?}); |
| 729 | try std.testing.expectFmt("add sp, x5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); | 1004 | try std.testing.expectFmt("add sp, x5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); |
| 730 | try std.testing.expectFmt("add x7, sp, w8, uxtw #2", "{f}", .{(try as.nextInstruction()).?}); | 1005 | try std.testing.expectFmt("add x7, sp, w8, uxtw #2", "{f}", .{(try as.nextInstruction()).?}); |
| 731 | try std.testing.expectFmt("add sp, sp, x9", "{f}", .{(try as.nextInstruction()).?}); | 1006 | try std.testing.expectFmt("add sp, sp, x9", "{f}", .{(try as.nextInstruction()).?}); |
| 732 | try std.testing.expectFmt("add x10, x10, xzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); | 1007 | try std.testing.expectFmt("add x10, x10, xzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); |
| 733 | try std.testing.expectFmt("add x11, x12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); | 1008 | try std.testing.expectFmt("add x11, x12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); |
| 734 | try std.testing.expectFmt("add sp, x13, wzr, sxth #0", "{f}", .{(try as.nextInstruction()).?}); | 1009 | try std.testing.expectFmt("add sp, x13, wzr, sxth", "{f}", .{(try as.nextInstruction()).?}); |
| 735 | try std.testing.expectFmt("add x14, sp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); | 1010 | try std.testing.expectFmt("add x14, sp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); |
| 736 | try std.testing.expectFmt("add sp, sp, xzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); | 1011 | try std.testing.expectFmt("add sp, sp, xzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); |
| 737 | | 1012 | |
| ... | @@ -785,6 +1060,125 @@ test "add sub" { | ... | @@ -785,6 +1060,125 @@ test "add sub" { |
| 785 | try std.testing.expectFmt("add xzr, xzr, x13, asr #31", "{f}", .{(try as.nextInstruction()).?}); | 1060 | try std.testing.expectFmt("add xzr, xzr, x13, asr #31", "{f}", .{(try as.nextInstruction()).?}); |
| 786 | try std.testing.expectFmt("add xzr, xzr, xzr, asr #63", "{f}", .{(try as.nextInstruction()).?}); | 1061 | try std.testing.expectFmt("add xzr, xzr, xzr, asr #63", "{f}", .{(try as.nextInstruction()).?}); |
| 787 | | 1062 | |
| | 1063 | try std.testing.expectFmt("addg x0, sp, #0x0, #0xf", "{f}", .{(try as.nextInstruction()).?}); |
| | 1064 | try std.testing.expectFmt("addg sp, x1, #0x3f0, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1065 | |
| | 1066 | try std.testing.expectFmt("adds w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1067 | try std.testing.expectFmt("adds w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); |
| | 1068 | try std.testing.expectFmt("adds w5, w5, w6", "{f}", .{(try as.nextInstruction()).?}); |
| | 1069 | try std.testing.expectFmt("adds w7, wsp, w8", "{f}", .{(try as.nextInstruction()).?}); |
| | 1070 | try std.testing.expectFmt("adds w9, wsp, w9", "{f}", .{(try as.nextInstruction()).?}); |
| | 1071 | try std.testing.expectFmt("adds w10, w10, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1072 | try std.testing.expectFmt("adds w11, w12, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1073 | try std.testing.expectFmt("cmn w13, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1074 | try std.testing.expectFmt("adds w14, wsp, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1075 | try std.testing.expectFmt("cmn wsp, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1076 | |
| | 1077 | try std.testing.expectFmt("adds x0, x0, x1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1078 | try std.testing.expectFmt("adds x2, x3, x4", "{f}", .{(try as.nextInstruction()).?}); |
| | 1079 | try std.testing.expectFmt("adds x5, x5, x6", "{f}", .{(try as.nextInstruction()).?}); |
| | 1080 | try std.testing.expectFmt("adds x7, sp, x8", "{f}", .{(try as.nextInstruction()).?}); |
| | 1081 | try std.testing.expectFmt("adds x9, sp, x9", "{f}", .{(try as.nextInstruction()).?}); |
| | 1082 | try std.testing.expectFmt("adds x10, x10, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1083 | try std.testing.expectFmt("adds x11, x12, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1084 | try std.testing.expectFmt("cmn x13, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1085 | try std.testing.expectFmt("adds x14, sp, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1086 | try std.testing.expectFmt("cmn sp, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1087 | |
| | 1088 | try std.testing.expectFmt("adds w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1089 | try std.testing.expectFmt("adds w2, w3, w4, uxtb", "{f}", .{(try as.nextInstruction()).?}); |
| | 1090 | try std.testing.expectFmt("cmn w5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1091 | try std.testing.expectFmt("adds w7, wsp, w8, lsl #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1092 | try std.testing.expectFmt("adds w9, wsp, w9, uxtx", "{f}", .{(try as.nextInstruction()).?}); |
| | 1093 | try std.testing.expectFmt("adds w10, w10, wzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); |
| | 1094 | try std.testing.expectFmt("adds w11, w12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); |
| | 1095 | try std.testing.expectFmt("cmn w13, wzr, sxth", "{f}", .{(try as.nextInstruction()).?}); |
| | 1096 | try std.testing.expectFmt("adds w14, wsp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1097 | try std.testing.expectFmt("cmn wsp, wzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1098 | |
| | 1099 | try std.testing.expectFmt("adds x0, x0, x1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1100 | try std.testing.expectFmt("adds x2, x3, w4, uxtb", "{f}", .{(try as.nextInstruction()).?}); |
| | 1101 | try std.testing.expectFmt("cmn x5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1102 | try std.testing.expectFmt("adds x7, sp, w8, uxtw #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1103 | try std.testing.expectFmt("cmn sp, x9", "{f}", .{(try as.nextInstruction()).?}); |
| | 1104 | try std.testing.expectFmt("adds x10, x10, xzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); |
| | 1105 | try std.testing.expectFmt("adds x11, x12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); |
| | 1106 | try std.testing.expectFmt("cmn x13, wzr, sxth", "{f}", .{(try as.nextInstruction()).?}); |
| | 1107 | try std.testing.expectFmt("adds x14, sp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1108 | try std.testing.expectFmt("cmn sp, xzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1109 | |
| | 1110 | try std.testing.expectFmt("adds w0, w0, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1111 | try std.testing.expectFmt("adds w0, w1, #0x1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1112 | try std.testing.expectFmt("adds wzr, w2, #0x2, lsl #12", "{f}", .{(try as.nextInstruction()).?}); |
| | 1113 | try std.testing.expectFmt("adds w3, wsp, #0x3", "{f}", .{(try as.nextInstruction()).?}); |
| | 1114 | try std.testing.expectFmt("adds wzr, wsp, #0xfff, lsl #12", "{f}", .{(try as.nextInstruction()).?}); |
| | 1115 | try std.testing.expectFmt("adds w0, w1, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1116 | try std.testing.expectFmt("adds w2, w3, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1117 | try std.testing.expectFmt("adds w4, wsp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1118 | try std.testing.expectFmt("adds w5, wsp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1119 | try std.testing.expectFmt("adds wzr, w6, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1120 | try std.testing.expectFmt("adds wzr, w7, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1121 | try std.testing.expectFmt("adds wzr, wsp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1122 | try std.testing.expectFmt("adds wzr, wsp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1123 | |
| | 1124 | try std.testing.expectFmt("adds x0, x0, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1125 | try std.testing.expectFmt("adds x0, x1, #0x1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1126 | try std.testing.expectFmt("adds xzr, x2, #0x2, lsl #12", "{f}", .{(try as.nextInstruction()).?}); |
| | 1127 | try std.testing.expectFmt("adds x3, sp, #0x3", "{f}", .{(try as.nextInstruction()).?}); |
| | 1128 | try std.testing.expectFmt("adds xzr, sp, #0xfff, lsl #12", "{f}", .{(try as.nextInstruction()).?}); |
| | 1129 | try std.testing.expectFmt("adds x0, x1, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1130 | try std.testing.expectFmt("adds x2, x3, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1131 | try std.testing.expectFmt("adds x4, sp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1132 | try std.testing.expectFmt("adds x5, sp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1133 | try std.testing.expectFmt("adds xzr, x6, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1134 | try std.testing.expectFmt("adds xzr, x7, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1135 | try std.testing.expectFmt("adds xzr, sp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1136 | try std.testing.expectFmt("adds xzr, sp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1137 | |
| | 1138 | try std.testing.expectFmt("adds w0, w0, w0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1139 | try std.testing.expectFmt("adds w1, w1, w2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1140 | try std.testing.expectFmt("adds w3, w4, w5, lsl #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1141 | try std.testing.expectFmt("adds w6, w6, wzr, lsl #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1142 | try std.testing.expectFmt("adds w7, wzr, w8, lsr #0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1143 | try std.testing.expectFmt("adds w9, wzr, wzr, lsr #30", "{f}", .{(try as.nextInstruction()).?}); |
| | 1144 | try std.testing.expectFmt("cmn w10, w11, lsr #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1145 | try std.testing.expectFmt("cmn w12, wzr, asr #0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1146 | try std.testing.expectFmt("cmn wzr, w13, asr #16", "{f}", .{(try as.nextInstruction()).?}); |
| | 1147 | try std.testing.expectFmt("cmn wzr, wzr, asr #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1148 | |
| | 1149 | try std.testing.expectFmt("adds x0, x0, x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1150 | try std.testing.expectFmt("adds x1, x1, x2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1151 | try std.testing.expectFmt("adds x3, x4, x5, lsl #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1152 | try std.testing.expectFmt("adds x6, x6, xzr, lsl #63", "{f}", .{(try as.nextInstruction()).?}); |
| | 1153 | try std.testing.expectFmt("adds x7, xzr, x8, lsr #0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1154 | try std.testing.expectFmt("adds x9, xzr, xzr, lsr #62", "{f}", .{(try as.nextInstruction()).?}); |
| | 1155 | try std.testing.expectFmt("cmn x10, x11, lsr #63", "{f}", .{(try as.nextInstruction()).?}); |
| | 1156 | try std.testing.expectFmt("cmn x12, xzr, asr #0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1157 | try std.testing.expectFmt("cmn xzr, x13, asr #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1158 | try std.testing.expectFmt("cmn xzr, xzr, asr #63", "{f}", .{(try as.nextInstruction()).?}); |
| | 1159 | |
| | 1160 | try std.testing.expectFmt("neg w0, w0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1161 | try std.testing.expectFmt("neg w1, w2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1162 | try std.testing.expectFmt("neg w3, wzr, lsl #7", "{f}", .{(try as.nextInstruction()).?}); |
| | 1163 | try std.testing.expectFmt("neg wzr, w4, lsr #14", "{f}", .{(try as.nextInstruction()).?}); |
| | 1164 | try std.testing.expectFmt("neg wzr, wzr, asr #21", "{f}", .{(try as.nextInstruction()).?}); |
| | 1165 | |
| | 1166 | try std.testing.expectFmt("neg x0, x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1167 | try std.testing.expectFmt("neg x1, x2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1168 | try std.testing.expectFmt("neg x3, xzr, lsl #11", "{f}", .{(try as.nextInstruction()).?}); |
| | 1169 | try std.testing.expectFmt("neg xzr, x4, lsr #22", "{f}", .{(try as.nextInstruction()).?}); |
| | 1170 | try std.testing.expectFmt("neg xzr, xzr, asr #33", "{f}", .{(try as.nextInstruction()).?}); |
| | 1171 | |
| | 1172 | try std.testing.expectFmt("sbc w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1173 | try std.testing.expectFmt("sbc w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); |
| | 1174 | try std.testing.expectFmt("sbc w5, w5, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1175 | try std.testing.expectFmt("sbc w6, w7, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1176 | |
| | 1177 | try std.testing.expectFmt("sbcs w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1178 | try std.testing.expectFmt("sbcs w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); |
| | 1179 | try std.testing.expectFmt("sbcs w5, w5, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1180 | try std.testing.expectFmt("sbcs w6, w7, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1181 | |
| 788 | try std.testing.expectFmt("sub w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); | 1182 | try std.testing.expectFmt("sub w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| 789 | try std.testing.expectFmt("sub w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); | 1183 | try std.testing.expectFmt("sub w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); |
| 790 | try std.testing.expectFmt("sub wsp, w5, w6", "{f}", .{(try as.nextInstruction()).?}); | 1184 | try std.testing.expectFmt("sub wsp, w5, w6", "{f}", .{(try as.nextInstruction()).?}); |
| ... | @@ -808,24 +1202,24 @@ test "add sub" { | ... | @@ -808,24 +1202,24 @@ test "add sub" { |
| 808 | try std.testing.expectFmt("sub sp, sp, xzr", "{f}", .{(try as.nextInstruction()).?}); | 1202 | try std.testing.expectFmt("sub sp, sp, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| 809 | | 1203 | |
| 810 | try std.testing.expectFmt("sub w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); | 1204 | try std.testing.expectFmt("sub w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| 811 | try std.testing.expectFmt("sub w2, w3, w4, uxtb #0", "{f}", .{(try as.nextInstruction()).?}); | 1205 | try std.testing.expectFmt("sub w2, w3, w4, uxtb", "{f}", .{(try as.nextInstruction()).?}); |
| 812 | try std.testing.expectFmt("sub wsp, w5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); | 1206 | try std.testing.expectFmt("sub wsp, w5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); |
| 813 | try std.testing.expectFmt("sub w7, wsp, w8", "{f}", .{(try as.nextInstruction()).?}); | 1207 | try std.testing.expectFmt("sub w7, wsp, w8, lsl #2", "{f}", .{(try as.nextInstruction()).?}); |
| 814 | try std.testing.expectFmt("sub wsp, wsp, w9, uxtw #2", "{f}", .{(try as.nextInstruction()).?}); | 1208 | try std.testing.expectFmt("sub wsp, wsp, w9, uxtx", "{f}", .{(try as.nextInstruction()).?}); |
| 815 | try std.testing.expectFmt("sub w10, w10, wzr, uxtw #3", "{f}", .{(try as.nextInstruction()).?}); | 1209 | try std.testing.expectFmt("sub w10, w10, wzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); |
| 816 | try std.testing.expectFmt("sub w11, w12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); | 1210 | try std.testing.expectFmt("sub w11, w12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); |
| 817 | try std.testing.expectFmt("sub wsp, w13, wzr, sxth #0", "{f}", .{(try as.nextInstruction()).?}); | 1211 | try std.testing.expectFmt("sub wsp, w13, wzr, sxth", "{f}", .{(try as.nextInstruction()).?}); |
| 818 | try std.testing.expectFmt("sub w14, wsp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); | 1212 | try std.testing.expectFmt("sub w14, wsp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); |
| 819 | try std.testing.expectFmt("sub wsp, wsp, wzr, sxtw #2", "{f}", .{(try as.nextInstruction()).?}); | 1213 | try std.testing.expectFmt("sub wsp, wsp, wzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); |
| 820 | | 1214 | |
| 821 | try std.testing.expectFmt("sub x0, x0, x1", "{f}", .{(try as.nextInstruction()).?}); | 1215 | try std.testing.expectFmt("sub x0, x0, x1", "{f}", .{(try as.nextInstruction()).?}); |
| 822 | try std.testing.expectFmt("sub x2, x3, w4, uxtb #0", "{f}", .{(try as.nextInstruction()).?}); | 1216 | try std.testing.expectFmt("sub x2, x3, w4, uxtb", "{f}", .{(try as.nextInstruction()).?}); |
| 823 | try std.testing.expectFmt("sub sp, x5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); | 1217 | try std.testing.expectFmt("sub sp, x5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); |
| 824 | try std.testing.expectFmt("sub x7, sp, w8, uxtw #2", "{f}", .{(try as.nextInstruction()).?}); | 1218 | try std.testing.expectFmt("sub x7, sp, w8, uxtw #2", "{f}", .{(try as.nextInstruction()).?}); |
| 825 | try std.testing.expectFmt("sub sp, sp, x9", "{f}", .{(try as.nextInstruction()).?}); | 1219 | try std.testing.expectFmt("sub sp, sp, x9", "{f}", .{(try as.nextInstruction()).?}); |
| 826 | try std.testing.expectFmt("sub x10, x10, xzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); | 1220 | try std.testing.expectFmt("sub x10, x10, xzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); |
| 827 | try std.testing.expectFmt("sub x11, x12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); | 1221 | try std.testing.expectFmt("sub x11, x12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); |
| 828 | try std.testing.expectFmt("sub sp, x13, wzr, sxth #0", "{f}", .{(try as.nextInstruction()).?}); | 1222 | try std.testing.expectFmt("sub sp, x13, wzr, sxth", "{f}", .{(try as.nextInstruction()).?}); |
| 829 | try std.testing.expectFmt("sub x14, sp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); | 1223 | try std.testing.expectFmt("sub x14, sp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); |
| 830 | try std.testing.expectFmt("sub sp, sp, xzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); | 1224 | try std.testing.expectFmt("sub sp, sp, xzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); |
| 831 | | 1225 | |
| ... | @@ -879,17 +1273,102 @@ test "add sub" { | ... | @@ -879,17 +1273,102 @@ test "add sub" { |
| 879 | try std.testing.expectFmt("neg xzr, x13, asr #31", "{f}", .{(try as.nextInstruction()).?}); | 1273 | try std.testing.expectFmt("neg xzr, x13, asr #31", "{f}", .{(try as.nextInstruction()).?}); |
| 880 | try std.testing.expectFmt("neg xzr, xzr, asr #63", "{f}", .{(try as.nextInstruction()).?}); | 1274 | try std.testing.expectFmt("neg xzr, xzr, asr #63", "{f}", .{(try as.nextInstruction()).?}); |
| 881 | | 1275 | |
| 882 | try std.testing.expectFmt("neg w0, w0", "{f}", .{(try as.nextInstruction()).?}); | 1276 | try std.testing.expectFmt("subg x0, sp, #0x0, #0xf", "{f}", .{(try as.nextInstruction()).?}); |
| 883 | try std.testing.expectFmt("neg w1, w2", "{f}", .{(try as.nextInstruction()).?}); | 1277 | try std.testing.expectFmt("subg sp, x1, #0x3f0, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| 884 | try std.testing.expectFmt("neg w3, wzr, lsl #7", "{f}", .{(try as.nextInstruction()).?}); | 1278 | |
| 885 | try std.testing.expectFmt("neg wzr, w4, lsr #14", "{f}", .{(try as.nextInstruction()).?}); | 1279 | try std.testing.expectFmt("subs w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| 886 | try std.testing.expectFmt("neg wzr, wzr, asr #21", "{f}", .{(try as.nextInstruction()).?}); | 1280 | try std.testing.expectFmt("subs w2, w3, w4", "{f}", .{(try as.nextInstruction()).?}); |
| 887 | | 1281 | try std.testing.expectFmt("subs w5, w5, w6", "{f}", .{(try as.nextInstruction()).?}); |
| 888 | try std.testing.expectFmt("neg x0, x0", "{f}", .{(try as.nextInstruction()).?}); | 1282 | try std.testing.expectFmt("subs w7, wsp, w8", "{f}", .{(try as.nextInstruction()).?}); |
| 889 | try std.testing.expectFmt("neg x1, x2", "{f}", .{(try as.nextInstruction()).?}); | 1283 | try std.testing.expectFmt("subs w9, wsp, w9", "{f}", .{(try as.nextInstruction()).?}); |
| 890 | try std.testing.expectFmt("neg x3, xzr, lsl #11", "{f}", .{(try as.nextInstruction()).?}); | 1284 | try std.testing.expectFmt("subs w10, w10, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| 891 | try std.testing.expectFmt("neg xzr, x4, lsr #22", "{f}", .{(try as.nextInstruction()).?}); | 1285 | try std.testing.expectFmt("subs w11, w12, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| 892 | try std.testing.expectFmt("neg xzr, xzr, asr #33", "{f}", .{(try as.nextInstruction()).?}); | 1286 | try std.testing.expectFmt("cmp w13, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1287 | try std.testing.expectFmt("subs w14, wsp, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1288 | try std.testing.expectFmt("cmp wsp, wzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1289 | |
| | 1290 | try std.testing.expectFmt("subs x0, x0, x1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1291 | try std.testing.expectFmt("subs x2, x3, x4", "{f}", .{(try as.nextInstruction()).?}); |
| | 1292 | try std.testing.expectFmt("subs x5, x5, x6", "{f}", .{(try as.nextInstruction()).?}); |
| | 1293 | try std.testing.expectFmt("subs x7, sp, x8", "{f}", .{(try as.nextInstruction()).?}); |
| | 1294 | try std.testing.expectFmt("subs x9, sp, x9", "{f}", .{(try as.nextInstruction()).?}); |
| | 1295 | try std.testing.expectFmt("subs x10, x10, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1296 | try std.testing.expectFmt("subs x11, x12, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1297 | try std.testing.expectFmt("cmp x13, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1298 | try std.testing.expectFmt("subs x14, sp, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1299 | try std.testing.expectFmt("cmp sp, xzr", "{f}", .{(try as.nextInstruction()).?}); |
| | 1300 | |
| | 1301 | try std.testing.expectFmt("subs w0, w0, w1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1302 | try std.testing.expectFmt("subs w2, w3, w4, uxtb", "{f}", .{(try as.nextInstruction()).?}); |
| | 1303 | try std.testing.expectFmt("cmp w5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1304 | try std.testing.expectFmt("subs w7, wsp, w8, lsl #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1305 | try std.testing.expectFmt("subs w9, wsp, w9, uxtx", "{f}", .{(try as.nextInstruction()).?}); |
| | 1306 | try std.testing.expectFmt("subs w10, w10, wzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); |
| | 1307 | try std.testing.expectFmt("subs w11, w12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); |
| | 1308 | try std.testing.expectFmt("cmp w13, wzr, sxth", "{f}", .{(try as.nextInstruction()).?}); |
| | 1309 | try std.testing.expectFmt("subs w14, wsp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1310 | try std.testing.expectFmt("cmp wsp, wzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1311 | |
| | 1312 | try std.testing.expectFmt("subs x0, x0, x1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1313 | try std.testing.expectFmt("subs x2, x3, w4, uxtb", "{f}", .{(try as.nextInstruction()).?}); |
| | 1314 | try std.testing.expectFmt("cmp x5, w6, uxth #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1315 | try std.testing.expectFmt("subs x7, sp, w8, uxtw #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1316 | try std.testing.expectFmt("cmp sp, x9", "{f}", .{(try as.nextInstruction()).?}); |
| | 1317 | try std.testing.expectFmt("subs x10, x10, xzr, uxtx #3", "{f}", .{(try as.nextInstruction()).?}); |
| | 1318 | try std.testing.expectFmt("subs x11, x12, wzr, sxtb #4", "{f}", .{(try as.nextInstruction()).?}); |
| | 1319 | try std.testing.expectFmt("cmp x13, wzr, sxth", "{f}", .{(try as.nextInstruction()).?}); |
| | 1320 | try std.testing.expectFmt("subs x14, sp, wzr, sxtw #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1321 | try std.testing.expectFmt("cmp sp, xzr, sxtx #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1322 | |
| | 1323 | try std.testing.expectFmt("subs w0, w0, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1324 | try std.testing.expectFmt("subs w0, w1, #0x1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1325 | try std.testing.expectFmt("subs wzr, w2, #0x2, lsl #12", "{f}", .{(try as.nextInstruction()).?}); |
| | 1326 | try std.testing.expectFmt("subs w3, wsp, #0x3", "{f}", .{(try as.nextInstruction()).?}); |
| | 1327 | try std.testing.expectFmt("subs wzr, wsp, #0xfff, lsl #12", "{f}", .{(try as.nextInstruction()).?}); |
| | 1328 | try std.testing.expectFmt("subs w0, w1, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1329 | try std.testing.expectFmt("subs w2, w3, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1330 | try std.testing.expectFmt("subs w4, wsp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1331 | try std.testing.expectFmt("subs w5, wsp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1332 | try std.testing.expectFmt("subs wzr, w6, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1333 | try std.testing.expectFmt("subs wzr, w7, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1334 | try std.testing.expectFmt("subs wzr, wsp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1335 | try std.testing.expectFmt("subs wzr, wsp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1336 | |
| | 1337 | try std.testing.expectFmt("subs x0, x0, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1338 | try std.testing.expectFmt("subs x0, x1, #0x1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1339 | try std.testing.expectFmt("subs xzr, x2, #0x2, lsl #12", "{f}", .{(try as.nextInstruction()).?}); |
| | 1340 | try std.testing.expectFmt("subs x3, sp, #0x3", "{f}", .{(try as.nextInstruction()).?}); |
| | 1341 | try std.testing.expectFmt("subs xzr, sp, #0xfff, lsl #12", "{f}", .{(try as.nextInstruction()).?}); |
| | 1342 | try std.testing.expectFmt("subs x0, x1, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1343 | try std.testing.expectFmt("subs x2, x3, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1344 | try std.testing.expectFmt("subs x4, sp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1345 | try std.testing.expectFmt("subs x5, sp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1346 | try std.testing.expectFmt("subs xzr, x6, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1347 | try std.testing.expectFmt("subs xzr, x7, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1348 | try std.testing.expectFmt("subs xzr, sp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1349 | try std.testing.expectFmt("subs xzr, sp, #0x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1350 | |
| | 1351 | try std.testing.expectFmt("subs w0, w0, w0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1352 | try std.testing.expectFmt("subs w1, w1, w2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1353 | try std.testing.expectFmt("subs w3, w4, w5, lsl #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1354 | try std.testing.expectFmt("subs w6, w6, wzr, lsl #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1355 | try std.testing.expectFmt("negs w7, w8, lsr #0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1356 | try std.testing.expectFmt("negs w9, wzr, lsr #30", "{f}", .{(try as.nextInstruction()).?}); |
| | 1357 | try std.testing.expectFmt("cmp w10, w11, lsr #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1358 | try std.testing.expectFmt("cmp w12, wzr, asr #0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1359 | try std.testing.expectFmt("cmp wzr, w13, asr #16", "{f}", .{(try as.nextInstruction()).?}); |
| | 1360 | try std.testing.expectFmt("cmp wzr, wzr, asr #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1361 | |
| | 1362 | try std.testing.expectFmt("subs x0, x0, x0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1363 | try std.testing.expectFmt("subs x1, x1, x2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1364 | try std.testing.expectFmt("subs x3, x4, x5, lsl #1", "{f}", .{(try as.nextInstruction()).?}); |
| | 1365 | try std.testing.expectFmt("subs x6, x6, xzr, lsl #63", "{f}", .{(try as.nextInstruction()).?}); |
| | 1366 | try std.testing.expectFmt("negs x7, x8, lsr #0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1367 | try std.testing.expectFmt("negs x9, xzr, lsr #62", "{f}", .{(try as.nextInstruction()).?}); |
| | 1368 | try std.testing.expectFmt("cmp x10, x11, lsr #63", "{f}", .{(try as.nextInstruction()).?}); |
| | 1369 | try std.testing.expectFmt("cmp x12, xzr, asr #0", "{f}", .{(try as.nextInstruction()).?}); |
| | 1370 | try std.testing.expectFmt("cmp xzr, x13, asr #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1371 | try std.testing.expectFmt("cmp xzr, xzr, asr #63", "{f}", .{(try as.nextInstruction()).?}); |
| 893 | | 1372 | |
| 894 | try std.testing.expect(null == try as.nextInstruction()); | 1373 | try std.testing.expect(null == try as.nextInstruction()); |
| 895 | } | 1374 | } |
| ... | @@ -966,44 +1445,62 @@ test "bit manipulation" { | ... | @@ -966,44 +1445,62 @@ test "bit manipulation" { |
| 966 | test "bitfield" { | 1445 | test "bitfield" { |
| 967 | var as: Assemble = .{ | 1446 | var as: Assemble = .{ |
| 968 | .source = | 1447 | .source = |
| 969 | \\sbfm w0, w0, #0, #31 | 1448 | \\bfc w0, #1, #31 |
| 970 | \\sbfm w0, w0, #31, #0 | 1449 | \\bfc w1, #31, #1 |
| 971 | \\ | 1450 | \\bfc x2, #1, #63 |
| 972 | \\sbfm x0, x0, #0, #63 | 1451 | \\bfc x3, #63, #1 |
| 973 | \\sbfm x0, x0, #63, #0 | 1452 | \\ |
| 974 | \\ | 1453 | \\bfi w0, w1, #1, #31 |
| 975 | \\bfm w0, w0, #0, #31 | 1454 | \\bfi w2, wzr, #31, #1 |
| 976 | \\bfm w0, w0, #31, #0 | 1455 | \\bfi x3, xzr, #1, #63 |
| 977 | \\ | 1456 | \\bfi x4, x5, #63, #1 |
| 978 | \\bfm x0, x0, #0, #63 | 1457 | \\ |
| 979 | \\bfm x0, x0, #63, #0 | 1458 | \\bfm w0, wzr, #25, #5 |
| 980 | \\ | 1459 | \\bfm w1, w2, #31, #1 |
| 981 | \\ubfm w0, w0, #0, #31 | 1460 | \\bfm w3, w4, #1, #31 |
| 982 | \\ubfm w0, w0, #31, #0 | 1461 | \\bfm x5, xzr, #57, #7 |
| 983 | \\ | 1462 | \\bfm x6, x7, #63, #1 |
| 984 | \\ubfm x0, x0, #0, #63 | 1463 | \\bfm x8, x9, #1, #63 |
| 985 | \\ubfm x0, x0, #63, #0 | 1464 | \\ |
| | 1465 | \\sbfm w0, w1, #31, #1 |
| | 1466 | \\sbfm w2, w3, #1, #31 |
| | 1467 | \\sbfm x4, x5, #63, #1 |
| | 1468 | \\sbfm x6, x7, #1, #63 |
| | 1469 | \\ |
| | 1470 | \\ubfm w0, w1, #31, #1 |
| | 1471 | \\ubfm w2, w3, #1, #31 |
| | 1472 | \\ubfm x4, x5, #63, #1 |
| | 1473 | \\ubfm x6, x7, #1, #63 |
| 986 | , | 1474 | , |
| 987 | .operands = .empty, | 1475 | .operands = .empty, |
| 988 | }; | 1476 | }; |
| 989 | | 1477 | |
| 990 | try std.testing.expectFmt("sbfm w0, w0, #0, #31", "{f}", .{(try as.nextInstruction()).?}); | 1478 | try std.testing.expectFmt("bfc w0, #1, #31", "{f}", .{(try as.nextInstruction()).?}); |
| 991 | try std.testing.expectFmt("sbfm w0, w0, #31, #0", "{f}", .{(try as.nextInstruction()).?}); | 1479 | try std.testing.expectFmt("bfc w1, #31, #1", "{f}", .{(try as.nextInstruction()).?}); |
| 992 | | 1480 | try std.testing.expectFmt("bfc x2, #1, #63", "{f}", .{(try as.nextInstruction()).?}); |
| 993 | try std.testing.expectFmt("sbfm x0, x0, #0, #63", "{f}", .{(try as.nextInstruction()).?}); | 1481 | try std.testing.expectFmt("bfc x3, #63, #1", "{f}", .{(try as.nextInstruction()).?}); |
| 994 | try std.testing.expectFmt("sbfm x0, x0, #63, #0", "{f}", .{(try as.nextInstruction()).?}); | 1482 | |
| 995 | | 1483 | try std.testing.expectFmt("bfi w0, w1, #1, #31", "{f}", .{(try as.nextInstruction()).?}); |
| 996 | try std.testing.expectFmt("bfm w0, w0, #0, #31", "{f}", .{(try as.nextInstruction()).?}); | 1484 | try std.testing.expectFmt("bfc w2, #31, #1", "{f}", .{(try as.nextInstruction()).?}); |
| 997 | try std.testing.expectFmt("bfm w0, w0, #31, #0", "{f}", .{(try as.nextInstruction()).?}); | 1485 | try std.testing.expectFmt("bfc x3, #1, #63", "{f}", .{(try as.nextInstruction()).?}); |
| 998 | | 1486 | try std.testing.expectFmt("bfi x4, x5, #63, #1", "{f}", .{(try as.nextInstruction()).?}); |
| 999 | try std.testing.expectFmt("bfm x0, x0, #0, #63", "{f}", .{(try as.nextInstruction()).?}); | 1487 | |
| 1000 | try std.testing.expectFmt("bfm x0, x0, #63, #0", "{f}", .{(try as.nextInstruction()).?}); | 1488 | try std.testing.expectFmt("bfc w0, #7, #6", "{f}", .{(try as.nextInstruction()).?}); |
| 1001 | | 1489 | try std.testing.expectFmt("bfi w1, w2, #1, #2", "{f}", .{(try as.nextInstruction()).?}); |
| 1002 | try std.testing.expectFmt("ubfm w0, w0, #0, #31", "{f}", .{(try as.nextInstruction()).?}); | 1490 | try std.testing.expectFmt("bfxil w3, w4, #1, #31", "{f}", .{(try as.nextInstruction()).?}); |
| 1003 | try std.testing.expectFmt("ubfm w0, w0, #31, #0", "{f}", .{(try as.nextInstruction()).?}); | 1491 | try std.testing.expectFmt("bfc x5, #7, #8", "{f}", .{(try as.nextInstruction()).?}); |
| 1004 | | 1492 | try std.testing.expectFmt("bfi x6, x7, #1, #2", "{f}", .{(try as.nextInstruction()).?}); |
| 1005 | try std.testing.expectFmt("ubfm x0, x0, #0, #63", "{f}", .{(try as.nextInstruction()).?}); | 1493 | try std.testing.expectFmt("bfxil x8, x9, #1, #63", "{f}", .{(try as.nextInstruction()).?}); |
| 1006 | try std.testing.expectFmt("ubfm x0, x0, #63, #0", "{f}", .{(try as.nextInstruction()).?}); | 1494 | |
| | 1495 | try std.testing.expectFmt("sbfiz w0, w1, #1, #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1496 | try std.testing.expectFmt("sbfx w2, w3, #1, #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1497 | try std.testing.expectFmt("sbfiz x4, x5, #1, #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1498 | try std.testing.expectFmt("sbfx x6, x7, #1, #63", "{f}", .{(try as.nextInstruction()).?}); |
| | 1499 | |
| | 1500 | try std.testing.expectFmt("ubfiz w0, w1, #1, #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1501 | try std.testing.expectFmt("ubfx w2, w3, #1, #31", "{f}", .{(try as.nextInstruction()).?}); |
| | 1502 | try std.testing.expectFmt("ubfiz x4, x5, #1, #2", "{f}", .{(try as.nextInstruction()).?}); |
| | 1503 | try std.testing.expectFmt("ubfx x6, x7, #1, #63", "{f}", .{(try as.nextInstruction()).?}); |
| 1007 | | 1504 | |
| 1008 | try std.testing.expect(null == try as.nextInstruction()); | 1505 | try std.testing.expect(null == try as.nextInstruction()); |
| 1009 | } | 1506 | } |
| ... | @@ -1113,6 +1610,22 @@ test "extract" { | ... | @@ -1113,6 +1610,22 @@ test "extract" { |
| 1113 | | 1610 | |
| 1114 | try std.testing.expect(null == try as.nextInstruction()); | 1611 | try std.testing.expect(null == try as.nextInstruction()); |
| 1115 | } | 1612 | } |
| | 1613 | test "flags" { |
| | 1614 | var as: Assemble = .{ |
| | 1615 | .source = |
| | 1616 | \\AXFLAG |
| | 1617 | \\CFINV |
| | 1618 | \\XAFLAG |
| | 1619 | , |
| | 1620 | .operands = .empty, |
| | 1621 | }; |
| | 1622 | |
| | 1623 | try std.testing.expectFmt("axflag", "{f}", .{(try as.nextInstruction()).?}); |
| | 1624 | try std.testing.expectFmt("cfinv", "{f}", .{(try as.nextInstruction()).?}); |
| | 1625 | try std.testing.expectFmt("xaflag", "{f}", .{(try as.nextInstruction()).?}); |
| | 1626 | |
| | 1627 | try std.testing.expect(null == try as.nextInstruction()); |
| | 1628 | } |
| 1116 | test "hints" { | 1629 | test "hints" { |
| 1117 | var as: Assemble = .{ | 1630 | var as: Assemble = .{ |
| 1118 | .source = | 1631 | .source = |
| ... | @@ -2935,6 +3448,5 @@ const aarch64 = @import("../aarch64.zig"); | ... | @@ -2935,6 +3448,5 @@ const aarch64 = @import("../aarch64.zig"); |
| 2935 | const Assemble = @This(); | 3448 | const Assemble = @This(); |
| 2936 | const assert = std.debug.assert; | 3449 | const assert = std.debug.assert; |
| 2937 | const Instruction = aarch64.encoding.Instruction; | 3450 | const Instruction = aarch64.encoding.Instruction; |
| 2938 | const instructions = @import("instructions.zon"); | | |
| 2939 | const std = @import("std"); | 3451 | const std = @import("std"); |
| 2940 | const log = std.log.scoped(.@"asm"); | 3452 | const log = std.log.scoped(.@"asm"); |