@@ -47,6 +47,7 @@ pub fn generate(
|
||||
.literals = .empty,
|
||||
.nav_relocs = .empty,
|
||||
.uav_relocs = .empty,
|
||||
.lazy_relocs = .empty,
|
||||
.global_relocs = .empty,
|
||||
.literal_relocs = .empty,
|
||||
|
||||
@@ -101,8 +102,8 @@ pub fn generate(
|
||||
};
|
||||
switch (passed_vi.parent(&isel)) {
|
||||
.unallocated => if (!mod.strip) {
|
||||
var part_it = arg_vi.parts(&isel);
|
||||
const first_passed_part_vi = part_it.next() orelse passed_vi;
|
||||
var part_it = passed_vi.parts(&isel);
|
||||
const first_passed_part_vi = part_it.next().?;
|
||||
const hint_ra = first_passed_part_vi.hint(&isel).?;
|
||||
passed_vi.setParent(&isel, .{ .stack_slot = if (hint_ra.isVector())
|
||||
isel.va_list.__vr_top.withOffset(@as(i8, -16) *
|
||||
@@ -167,6 +168,7 @@ pub fn generate(
|
||||
.literals = &.{},
|
||||
.nav_relocs = &.{},
|
||||
.uav_relocs = &.{},
|
||||
.lazy_relocs = &.{},
|
||||
.global_relocs = &.{},
|
||||
.literal_relocs = &.{},
|
||||
};
|
||||
@@ -174,6 +176,7 @@ pub fn generate(
|
||||
mir.literals = try isel.literals.toOwnedSlice(gpa);
|
||||
mir.nav_relocs = try isel.nav_relocs.toOwnedSlice(gpa);
|
||||
mir.uav_relocs = try isel.uav_relocs.toOwnedSlice(gpa);
|
||||
mir.lazy_relocs = try isel.lazy_relocs.toOwnedSlice(gpa);
|
||||
mir.global_relocs = try isel.global_relocs.toOwnedSlice(gpa);
|
||||
mir.literal_relocs = try isel.literal_relocs.toOwnedSlice(gpa);
|
||||
return mir;
|
||||
|
||||
@@ -6,14 +6,19 @@ pub const Operand = union(enum) {
|
||||
};
|
||||
|
||||
pub fn nextInstruction(as: *Assemble) !?Instruction {
|
||||
@setEvalBranchQuota(37_000);
|
||||
@setEvalBranchQuota(42_000);
|
||||
comptime var ct_token_buf: [token_buf_len]u8 = undefined;
|
||||
var token_buf: [token_buf_len]u8 = undefined;
|
||||
const original_source = while (true) {
|
||||
const original_source = as.source;
|
||||
const source_token = try as.nextToken(&token_buf, .{});
|
||||
if (source_token.len == 0) return null;
|
||||
if (source_token[0] != '\n') break original_source;
|
||||
switch (source_token.len) {
|
||||
0 => return null,
|
||||
else => switch (source_token[0]) {
|
||||
else => break original_source,
|
||||
'\n', ';' => {},
|
||||
},
|
||||
}
|
||||
};
|
||||
log.debug(
|
||||
\\.
|
||||
@@ -52,7 +57,13 @@ pub fn nextInstruction(as: *Assemble) !?Instruction {
|
||||
std.zig.fmtString(source_token),
|
||||
});
|
||||
if (pattern_token.len == 0) {
|
||||
if (source_token.len > 0 and source_token[0] != '\n') break :next_pattern;
|
||||
switch (source_token.len) {
|
||||
0 => {},
|
||||
else => switch (source_token[0]) {
|
||||
else => break :next_pattern,
|
||||
'\n', ';' => {},
|
||||
},
|
||||
}
|
||||
const encode = @field(Instruction, @tagName(instruction.encode[0]));
|
||||
const Encode = @TypeOf(encode);
|
||||
var args: std.meta.ArgsTuple(Encode) = undefined;
|
||||
@@ -65,7 +76,7 @@ pub fn nextInstruction(as: *Assemble) !?Instruction {
|
||||
const symbol = &@field(symbols, symbol_name);
|
||||
symbol.* = zonCast(SymbolSpec, @field(instruction.symbols, symbol_name), .{}).parse(source_token) orelse break :next_pattern;
|
||||
log.debug("{s} = {any}", .{ symbol_name, symbol.* });
|
||||
} else if (!std.ascii.eqlIgnoreCase(pattern_token, source_token)) break :next_pattern;
|
||||
} else if (!toUpperEqlAssertUpper(source_token, pattern_token)) break :next_pattern;
|
||||
}
|
||||
}
|
||||
log.debug("'{s}' not matched...", .{instruction.pattern});
|
||||
@@ -125,6 +136,15 @@ fn zonCast(comptime Result: type, zon_value: anytype, symbols: anytype) Result {
|
||||
}
|
||||
}
|
||||
|
||||
fn toUpperEqlAssertUpper(lhs: []const u8, rhs: []const u8) bool {
|
||||
if (lhs.len != rhs.len) return false;
|
||||
for (lhs, rhs) |l, r| {
|
||||
assert(!std.ascii.isLower(r));
|
||||
if (std.ascii.toUpper(l) != r) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const token_buf_len = "v31.b[15]".len;
|
||||
fn nextToken(as: *Assemble, buf: *[token_buf_len]u8, comptime opts: struct {
|
||||
operands: bool = false,
|
||||
@@ -134,7 +154,7 @@ fn nextToken(as: *Assemble, buf: *[token_buf_len]u8, comptime opts: struct {
|
||||
while (true) c: switch (as.source[0]) {
|
||||
0 => return as.source[0..0],
|
||||
'\t', '\n' + 1...'\r', ' ' => as.source = as.source[1..],
|
||||
'\n', '!', '#', ',', '[', ']' => {
|
||||
'\n', '!', '#', ',', ';', '[', ']' => {
|
||||
defer as.source = as.source[1..];
|
||||
return as.source[0..1];
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ epilogue: []const Instruction,
|
||||
literals: []const u32,
|
||||
nav_relocs: []const Reloc.Nav,
|
||||
uav_relocs: []const Reloc.Uav,
|
||||
lazy_relocs: []const Reloc.Lazy,
|
||||
global_relocs: []const Reloc.Global,
|
||||
literal_relocs: []const Reloc.Literal,
|
||||
|
||||
@@ -21,8 +22,13 @@ pub const Reloc = struct {
|
||||
reloc: Reloc,
|
||||
};
|
||||
|
||||
pub const Lazy = struct {
|
||||
symbol: link.File.LazySymbol,
|
||||
reloc: Reloc,
|
||||
};
|
||||
|
||||
pub const Global = struct {
|
||||
global: [*:0]const u8,
|
||||
name: [*:0]const u8,
|
||||
reloc: Reloc,
|
||||
};
|
||||
|
||||
@@ -38,6 +44,7 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
|
||||
gpa.free(mir.literals);
|
||||
gpa.free(mir.nav_relocs);
|
||||
gpa.free(mir.uav_relocs);
|
||||
gpa.free(mir.lazy_relocs);
|
||||
gpa.free(mir.global_relocs);
|
||||
gpa.free(mir.literal_relocs);
|
||||
mir.* = undefined;
|
||||
@@ -119,16 +126,37 @@ pub fn emit(
|
||||
body_end - Instruction.size * (1 + uav_reloc.reloc.label),
|
||||
uav_reloc.reloc.addend,
|
||||
);
|
||||
for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
|
||||
lf,
|
||||
zcu,
|
||||
func.owner_nav,
|
||||
if (lf.cast(.elf)) |ef|
|
||||
ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err|
|
||||
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
|
||||
else if (lf.cast(.macho)) |mf|
|
||||
mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |err|
|
||||
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
|
||||
else if (lf.cast(.coff)) |cf|
|
||||
if (cf.getOrCreateAtomForLazySymbol(pt, lazy_reloc.symbol)) |atom|
|
||||
cf.getAtom(atom).getSymbolIndex().?
|
||||
else |err|
|
||||
return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
|
||||
else
|
||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
||||
mir.body[lazy_reloc.reloc.label],
|
||||
body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
|
||||
lazy_reloc.reloc.addend,
|
||||
);
|
||||
for (mir.global_relocs) |global_reloc| try emitReloc(
|
||||
lf,
|
||||
zcu,
|
||||
func.owner_nav,
|
||||
if (lf.cast(.elf)) |ef|
|
||||
try ef.getGlobalSymbol(std.mem.span(global_reloc.global), null)
|
||||
try ef.getGlobalSymbol(std.mem.span(global_reloc.name), null)
|
||||
else if (lf.cast(.macho)) |mf|
|
||||
try mf.getGlobalSymbol(std.mem.span(global_reloc.global), null)
|
||||
try mf.getGlobalSymbol(std.mem.span(global_reloc.name), null)
|
||||
else if (lf.cast(.coff)) |cf|
|
||||
try cf.getGlobalSymbol(std.mem.span(global_reloc.global), "compiler_rt")
|
||||
try cf.getGlobalSymbol(std.mem.span(global_reloc.name), "compiler_rt")
|
||||
else
|
||||
return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
|
||||
mir.body[global_reloc.reloc.label],
|
||||
@@ -172,35 +200,6 @@ fn emitReloc(
|
||||
const gpa = zcu.gpa;
|
||||
switch (instruction.decode()) {
|
||||
else => unreachable,
|
||||
.branch_exception_generating_system => |decoded| if (lf.cast(.elf)) |ef| {
|
||||
const zo = ef.zigObjectPtr().?;
|
||||
const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
|
||||
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().unconditional_branch_immediate.group.op) {
|
||||
.b => .JUMP26,
|
||||
.bl => .CALL26,
|
||||
};
|
||||
try atom.addReloc(gpa, .{
|
||||
.r_offset = offset,
|
||||
.r_info = @as(u64, sym_index) << 32 | @intFromEnum(r_type),
|
||||
.r_addend = @bitCast(addend),
|
||||
}, zo);
|
||||
} else if (lf.cast(.macho)) |mf| {
|
||||
const zo = mf.getZigObject().?;
|
||||
const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
|
||||
try atom.addReloc(mf, .{
|
||||
.tag = .@"extern",
|
||||
.offset = offset,
|
||||
.target = sym_index,
|
||||
.addend = @bitCast(addend),
|
||||
.type = .branch,
|
||||
.meta = .{
|
||||
.pcrel = true,
|
||||
.has_subtractor = false,
|
||||
.length = 2,
|
||||
.symbolnum = @intCast(sym_index),
|
||||
},
|
||||
});
|
||||
},
|
||||
.data_processing_immediate => |decoded| if (lf.cast(.elf)) |ef| {
|
||||
const zo = ef.zigObjectPtr().?;
|
||||
const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
|
||||
@@ -259,6 +258,80 @@ fn emitReloc(
|
||||
},
|
||||
}
|
||||
},
|
||||
.branch_exception_generating_system => |decoded| if (lf.cast(.elf)) |ef| {
|
||||
const zo = ef.zigObjectPtr().?;
|
||||
const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
|
||||
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().unconditional_branch_immediate.group.op) {
|
||||
.b => .JUMP26,
|
||||
.bl => .CALL26,
|
||||
};
|
||||
try atom.addReloc(gpa, .{
|
||||
.r_offset = offset,
|
||||
.r_info = @as(u64, sym_index) << 32 | @intFromEnum(r_type),
|
||||
.r_addend = @bitCast(addend),
|
||||
}, zo);
|
||||
} else if (lf.cast(.macho)) |mf| {
|
||||
const zo = mf.getZigObject().?;
|
||||
const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
|
||||
try atom.addReloc(mf, .{
|
||||
.tag = .@"extern",
|
||||
.offset = offset,
|
||||
.target = sym_index,
|
||||
.addend = @bitCast(addend),
|
||||
.type = .branch,
|
||||
.meta = .{
|
||||
.pcrel = true,
|
||||
.has_subtractor = false,
|
||||
.length = 2,
|
||||
.symbolnum = @intCast(sym_index),
|
||||
},
|
||||
});
|
||||
},
|
||||
.load_store => |decoded| if (lf.cast(.elf)) |ef| {
|
||||
const zo = ef.zigObjectPtr().?;
|
||||
const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?;
|
||||
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
|
||||
.integer => |integer| switch (integer.decode()) {
|
||||
.unallocated, .prfm => unreachable,
|
||||
.strb, .ldrb, .ldrsb => .LDST8_ABS_LO12_NC,
|
||||
.strh, .ldrh, .ldrsh => .LDST16_ABS_LO12_NC,
|
||||
.ldrsw => .LDST32_ABS_LO12_NC,
|
||||
inline .str, .ldr => |encoded| switch (encoded.sf) {
|
||||
.word => .LDST32_ABS_LO12_NC,
|
||||
.doubleword => .LDST64_ABS_LO12_NC,
|
||||
},
|
||||
},
|
||||
.vector => |vector| switch (vector.group.opc1.decode(vector.group.size)) {
|
||||
.byte => .LDST8_ABS_LO12_NC,
|
||||
.half => .LDST16_ABS_LO12_NC,
|
||||
.single => .LDST32_ABS_LO12_NC,
|
||||
.double => .LDST64_ABS_LO12_NC,
|
||||
.quad => .LDST128_ABS_LO12_NC,
|
||||
.scalable, .predicate => unreachable,
|
||||
},
|
||||
};
|
||||
try atom.addReloc(gpa, .{
|
||||
.r_offset = offset,
|
||||
.r_info = @as(u64, sym_index) << 32 | @intFromEnum(r_type),
|
||||
.r_addend = @bitCast(addend),
|
||||
}, zo);
|
||||
} else if (lf.cast(.macho)) |mf| {
|
||||
const zo = mf.getZigObject().?;
|
||||
const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?;
|
||||
try atom.addReloc(mf, .{
|
||||
.tag = .@"extern",
|
||||
.offset = offset,
|
||||
.target = sym_index,
|
||||
.addend = @bitCast(addend),
|
||||
.type = .pageoff,
|
||||
.meta = .{
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
.length = 2,
|
||||
.symbolnum = @intCast(sym_index),
|
||||
},
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -213,6 +213,63 @@
|
||||
},
|
||||
.encode = .{ .ands, .Xd, .Xn, .{ .shifted_register_explicit = .{ .register = .Xm, .shift = .shift, .amount = .amount } } },
|
||||
},
|
||||
// C6.2.16 ASR (register)
|
||||
.{
|
||||
.pattern = "ASR <Wd>, <Wn>, <Wm>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
},
|
||||
.encode = .{ .asrv, .Wd, .Wn, .Wm },
|
||||
},
|
||||
.{
|
||||
.pattern = "ASR <Xd>, <Xn>, <Xm>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
},
|
||||
.encode = .{ .asrv, .Xd, .Xn, .Xm },
|
||||
},
|
||||
// C6.2.17 ASR (immediate)
|
||||
.{
|
||||
.pattern = "ASR <Wd>, <Wn>, #<shift>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 5 } } },
|
||||
},
|
||||
.encode = .{ .sbfm, .Wd, .Wn, .{ .N = .word, .immr = .shift, .imms = 31 } },
|
||||
},
|
||||
.{
|
||||
.pattern = "ASR <Xd>, <Xn>, #<shift>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 6 } } },
|
||||
},
|
||||
.encode = .{ .sbfm, .Xd, .Xn, .{ .N = .doubleword, .immr = .shift, .imms = 63 } },
|
||||
},
|
||||
// C6.2.18 ASRV
|
||||
.{
|
||||
.pattern = "ASRV <Wd>, <Wn>, <Wm>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
},
|
||||
.encode = .{ .asrv, .Wd, .Wn, .Wm },
|
||||
},
|
||||
.{
|
||||
.pattern = "ASRV <Xd>, <Xn>, <Xm>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
},
|
||||
.encode = .{ .asrv, .Xd, .Xn, .Xm },
|
||||
},
|
||||
// C6.2.35 BLR
|
||||
.{
|
||||
.pattern = "BLR <Xn>",
|
||||
@@ -681,6 +738,82 @@
|
||||
},
|
||||
.encode = .{ .ldr, .Xt, .{ .unsigned_offset = .{ .base = .Xn, .offset = .pimm } } },
|
||||
},
|
||||
// C6.2.212 LSL (register)
|
||||
.{
|
||||
.pattern = "LSL <Wd>, <Wn>, <Wm>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
},
|
||||
.encode = .{ .lslv, .Wd, .Wn, .Wm },
|
||||
},
|
||||
.{
|
||||
.pattern = "LSL <Xd>, <Xn>, <Xm>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
},
|
||||
.encode = .{ .lslv, .Xd, .Xn, .Xm },
|
||||
},
|
||||
// C6.2.214 LSLV
|
||||
.{
|
||||
.pattern = "LSLV <Wd>, <Wn>, <Wm>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
},
|
||||
.encode = .{ .lslv, .Wd, .Wn, .Wm },
|
||||
},
|
||||
.{
|
||||
.pattern = "LSLV <Xd>, <Xn>, <Xm>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
},
|
||||
.encode = .{ .lslv, .Xd, .Xn, .Xm },
|
||||
},
|
||||
// C6.2.215 LSR (register)
|
||||
.{
|
||||
.pattern = "LSR <Wd>, <Wn>, <Wm>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
},
|
||||
.encode = .{ .lsrv, .Wd, .Wn, .Wm },
|
||||
},
|
||||
.{
|
||||
.pattern = "LSR <Xd>, <Xn>, <Xm>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
},
|
||||
.encode = .{ .lsrv, .Xd, .Xn, .Xm },
|
||||
},
|
||||
// C6.2.217 LSRV
|
||||
.{
|
||||
.pattern = "LSRV <Wd>, <Wn>, <Wm>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
},
|
||||
.encode = .{ .lsrv, .Wd, .Wn, .Wm },
|
||||
},
|
||||
.{
|
||||
.pattern = "LSRV <Xd>, <Xn>, <Xm>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
},
|
||||
.encode = .{ .lsrv, .Xd, .Xn, .Xm },
|
||||
},
|
||||
// C6.2.220 MOV (to/from SP)
|
||||
.{
|
||||
.pattern = "MOV WSP, <Wn|WSP>",
|
||||
@@ -964,6 +1097,63 @@
|
||||
},
|
||||
.encode = .{ .ret, .Xn },
|
||||
},
|
||||
// C6.2.261 ROR (immediate)
|
||||
.{
|
||||
.pattern = "ROR <Wd>, <Ws>, #<shift>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Ws = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 5 } } },
|
||||
},
|
||||
.encode = .{ .extr, .Wd, .Ws, .Ws, .shift },
|
||||
},
|
||||
.{
|
||||
.pattern = "ROR <Xd>, <Xs>, #<shift>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xs = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.shift = .{ .imm = .{ .type = .{ .signedness = .unsigned, .bits = 6 } } },
|
||||
},
|
||||
.encode = .{ .extr, .Xd, .Xs, .Xs, .shift },
|
||||
},
|
||||
// C6.2.262 ROR (register)
|
||||
.{
|
||||
.pattern = "ROR <Wd>, <Wn>, <Wm>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
},
|
||||
.encode = .{ .rorv, .Wd, .Wn, .Wm },
|
||||
},
|
||||
.{
|
||||
.pattern = "ROR <Xd>, <Xn>, <Xm>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
},
|
||||
.encode = .{ .rorv, .Xd, .Xn, .Xm },
|
||||
},
|
||||
// C6.2.263 RORV
|
||||
.{
|
||||
.pattern = "RORV <Wd>, <Wn>, <Wm>",
|
||||
.symbols = .{
|
||||
.Wd = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wn = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
.Wm = .{ .reg = .{ .format = .{ .integer = .word } } },
|
||||
},
|
||||
.encode = .{ .rorv, .Wd, .Wn, .Wm },
|
||||
},
|
||||
.{
|
||||
.pattern = "RORV <Xd>, <Xn>, <Xm>",
|
||||
.symbols = .{
|
||||
.Xd = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xn = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
.Xm = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
|
||||
},
|
||||
.encode = .{ .rorv, .Xd, .Xn, .Xm },
|
||||
},
|
||||
// C6.2.268 SBFM
|
||||
.{
|
||||
.pattern = "SBFM <Wd>, <Wn>, #<immr>, #<imms>",
|
||||
|
||||
Reference in New Issue
Block a user