Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions instrs-user.sail
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,57 @@ function clause execute CompareAndBranch(sf, t, offset, iszero) = {
else _PC = _PC + 4;
}

/* Logical Shift: LSL/LSR (extend with ASR/ROR by adding cases below)
* sf (size flag): 0 = 32-bit (W registers), 1 = 64-bit (X registers) */
union clause ast = LogicalShift : (datasize, shift_op, reg_index, reg_index, operand)

/* LSL/LSR (immediate) - aliases of UBFM: sf 10 100110 N immr imms Rn Rd
* LSR: imms is all-ones for the size; shift = immr
* LSL: imms+1 == immr (mod size); shift = size-1-imms */
function clause decode ([sf]@0b10@0b100110@[N]@(immr:bits(6))@(imms:bits(6))@(Rn:bits(5))@(Rd:bits(5))) = {
let d : reg_index = unsigned(Rd);
let n : reg_index = unsigned(Rn);
let valid_size = (sf == bitone & N == bitone) | (sf == bitzero & N == bitzero);
if not_bool(valid_size) then return None();
let size_imms : bits(6) = if sf == bitone then 0b111111 else 0b011111;
if imms == size_imms then
Some(LogicalShift((sf, Lsr, d, n, OperandImm(sail_zero_extend(immr, 64)))))
else if (unsigned(imms) + 1) == unsigned(immr) then {
let shift : bits(6) = size_imms - imms;
Some(LogicalShift((sf, Lsl, d, n, OperandImm(sail_zero_extend(shift, 64)))))
}
else None()
}

/* LSL/LSR (register) - LSLV/LSRV: sf 0 0 11010110 Rm 0010 op2 Rn Rd
* op2: 00 = LSL, 01 = LSR (10 = ASR, 11 = ROR — future) */
function clause decode ([sf]@0b0@0b0@0b11010110@(Rm:bits(5))@0b0010@(op2:bits(2))@(Rn:bits(5))@(Rd:bits(5))) = {
let d : reg_index = unsigned(Rd);
let n : reg_index = unsigned(Rn);
let m : reg_index = unsigned(Rm);
match op2 {
0b00 => Some(LogicalShift((sf, Lsl, d, n, OperandReg(m)))),
0b01 => Some(LogicalShift((sf, Lsr, d, n, OperandReg(m)))),
_ => None()
}
}

/* LSL/LSR Xd/Wd, Xn/Wn, Xm/Wm or LSL/LSR Xd/Wd, Xn/Wn, #shift */
function clause execute LogicalShift(sf, op, d, n, oper) = {
_PC = _PC + 4;
let 'size = if sf == bitone then 64 else 32;
let raw : bits('size) = match oper {
OperandReg(m) => XS(m, size),
OperandImm(imm) => imm[size - 1 .. 0]
};
let shift_amount : int = tmod_int(unsigned(raw), size);
let result : bits('size) = match op {
Lsl => sail_shiftleft(XS(n, size), shift_amount),
Lsr => sail_shiftright(XS(n, size), shift_amount)
};
XS(d, size) = result;
}

/* Unconditional Branch: B */
union clause ast = Branch : bits(64)

Expand Down
6 changes: 6 additions & 0 deletions registers.sail
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ enum bitwise_op = {
And,
}

/* Shift operations (extend with Asr, Ror as needed) */
enum shift_op = {
Lsl,
Lsr,
}

register _PC : bits(64)

/* General purpose registers */
Expand Down