Skip to content
Open
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
293 changes: 180 additions & 113 deletions architecture/MIPS32.yml

Large diffs are not rendered by default.

30 changes: 9 additions & 21 deletions architecture/RISCV/RV32IMFD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3822,14 +3822,8 @@ pseudoinstructions:
- field: addr
type: imm-unsigned
definition: |
no_ret_op{
tmp = Field.2.(31,0).int - (reg.pc - 4);
tmp_low = tmp & 0x00000FFF;
tmp_low = tmp_low>0x7FF? tmp_low - 0x1000 : tmp_low;
tmp_hi = (tmp - tmp_low) >> 12;
};
auipc rd, op{tmp_hi};
addi rd, rd, op{tmp_low};
auipc rd, %hi(addr - .);
addi rd, rd, %lo(addr - (. - 4));

- name: li
fields:
Expand All @@ -3839,19 +3833,13 @@ pseudoinstructions:
- field: val
type: imm-signed
definition: |
no_ret_op{
tmp = Field.2.(31,0).int;
tmp_low = tmp & 0x00000FFF;
tmp_low -= tmp_low > 0x7FF ? 0x1000 : 0;
tmp_hi = (tmp - tmp_low) >>> 12;
};
if (tmp_hi === 0) {
addi rd, x0, op{tmp_low};
}
else {
lui rd, op{tmp_hi};
addi rd, rd, op{tmp_low};
};
js:
const val = args[1];
if (CAPI.FP.check_int_size(val, 32, 12)) return "addi rd, x0, %lo(val)";
return `
lui rd, %hi(val);
addi rd, rd, %lo(val);
`
help: Load the sign-extended 6-bit immediate, imm, into register rd.

- name: mv
Expand Down
29 changes: 16 additions & 13 deletions architecture/RISCV/RV64IMFD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,16 @@ memory_layout:
start: 0x0FFFFFFC
end: 0x0FFFFFFF

modifiers:
hi:
lower_signed: true
output_signed: false
range: [12, 32]
lo:
lower_signed: false
output_signed: true
range: [0, 12]

templates:
- name: B
type: Conditional bifurcation
Expand Down Expand Up @@ -4032,14 +4042,8 @@ pseudoinstructions:
- field: addr
type: imm-unsigned
definition: |
no_ret_op{
tmp = Field.2.(31,0).int - (reg.pc - 4);
tmp_low = tmp & 0x00000FFF;
tmp_low = tmp_low>0x7FF? tmp_low - 0x1000 : tmp_low;
tmp_hi = (tmp - tmp_low) >> 12;
};
auipc rd, op{tmp_hi};
addi rd, rd, op{tmp_low};
auipc rd, %hi(addr - .);
addi rd, rd, %lo(addr - (. - 4));

- name: li
fields:
Expand All @@ -4050,11 +4054,10 @@ pseudoinstructions:
type: imm-signed
# For legibility purposes, the implementation is included in the CREATOR codebase as a module.
definition: |
no_ret_op{
value = Field.2.(63,0).int;
res_instructions = CAPI.ARCH.generateLoadImmediate(value, reg_name{1});
};
op{res_instructions};
js:
const val = args[1];
if (val === null) throw "Invalid `val` expression.\nNote: Forward references aren't allowed";
return CAPI.ARCH.generateLoadImmediate(val, "rd");

- name: mv
fields:
Expand Down
40 changes: 19 additions & 21 deletions architecture/RISCV/SRV32.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,16 @@ memory_layout:
start: 0x8000AFFC
end: 0x8000AFFF

modifiers:
hi:
lower_signed: true
output_signed: false
range: [12, 32]
lo:
lower_signed: false
output_signed: true
range: [0, 12]

templates:
- name: B
type: Conditional bifurcation
Expand Down Expand Up @@ -4368,14 +4378,8 @@ pseudoinstructions:
- field: addr
type: imm-unsigned
definition: |
no_ret_op{
tmp = Field.2.(31,0).int - (reg.pc - 4);
tmp_low = tmp & 0x00000FFF;
tmp_low = tmp_low>0x7FF? tmp_low - 0x1000 : tmp_low;
tmp_hi = (tmp - tmp_low) >> 12;
};
auipc rd, op{tmp_hi};
addi rd, rd, op{tmp_low};
auipc rd, %hi(addr - .);
addi rd, rd, %lo(addr - (. - 4));

- name: li
extension: I
Expand All @@ -4386,19 +4390,13 @@ pseudoinstructions:
- field: val
type: imm-signed
definition: |
no_ret_op{
tmp = Field.2.(31,0).int;
tmp_low = tmp & 0x00000FFF;
tmp_low -= tmp_low > 0x7FF ? 0x1000 : 0;
tmp_hi = (tmp - tmp_low) >>> 12;
};
if (tmp_hi === 0) {
addi rd, x0, op{tmp_low};
}
else {
lui rd, op{tmp_hi};
addi rd, rd, op{tmp_low};
};
js:
const val = args[1];
if (CAPI.FP.check_int_size(val, 32, 12)) return "addi rd, x0, %lo(val)";
return `
lui rd, %hi(val);
addi rd, rd, %lo(val);
`
help: Load the sign-extended 6-bit immediate, imm, into register rd.

- name: mv
Expand Down
40 changes: 19 additions & 21 deletions architecture/RISCV/SRV64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,16 @@ memory_layout:
# start: 140737488355324
# end: 140737488355327

modifiers:
hi:
lower_signed: true
output_signed: false
range: [12, 32]
lo:
lower_signed: false
output_signed: true
range: [0, 12]

templates:
- name: B
type: Conditional bifurcation
Expand Down Expand Up @@ -4356,14 +4366,8 @@ pseudoinstructions:
- field: addr
type: imm-unsigned
definition: |
no_ret_op{
tmp = Field.2.(31,0).int - (reg.pc - 4);
tmp_low = tmp & 0x00000FFF;
tmp_low = tmp_low>0x7FF? tmp_low - 0x1000 : tmp_low;
tmp_hi = (tmp - tmp_low) >> 12;
};
auipc rd, op{tmp_hi};
addi rd, rd, op{tmp_low};
auipc rd, %hi(addr - .);
addi rd, rd, %lo(addr - (. - 4));

- name: li
extension: I
Expand All @@ -4374,19 +4378,13 @@ pseudoinstructions:
- field: val
type: imm-signed
definition: |
no_ret_op{
tmp = Field.2.(31,0).int;
tmp_low = tmp & 0x00000FFF;
tmp_low -= tmp_low > 0x7FF ? 0x1000 : 0;
tmp_hi = (tmp - tmp_low) >>> 12;
};
if (tmp_hi === 0) {
addi rd, x0, op{tmp_low};
}
else {
lui rd, op{tmp_hi};
addi rd, rd, op{tmp_low};
};
js:
const val = args[1];
if (CAPI.FP.check_int_size(val, 32, 12)) return "addi rd, x0, %lo(val)";
return `
lui rd, %hi(val);
addi rd, rd, %lo(val);
`
help: Load the sign-extended 6-bit immediate, imm, into register rd.

- name: mv
Expand Down
2 changes: 1 addition & 1 deletion docs/schema/architecture.json
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,7 @@
"required": ["definition", "name"],
"properties": {
"definition": {
"description": "Code to execute for the instruction",
"description": "Pseudoinstruction expansion definition. Can be either a instruction sequence template or a `JS` function\n\n# Instruction Sequence Form\n\nA string containing a newline/semicolon separated list of assembly instructions. Each instruction will be assembled as if it was specified by the user.\n\nIdentifiers in sub-expressions that match the name of one of the pseudoinstruction's fields will be automatically replaced with the corresponding argument's value. This allows forwarding the arguments and manipulation of the arguments within expressions. Forward references are supported when using this form.\n\n# Function Form\n\nA `JS` function body prefixed by `js:\\n`. The signature of this function should be:\n\n```ts\n(pc: bigint, args: Array<number | bigint | string | null>) => string\n```\n\nWhere:\n\n- `pc`: address in which the pseudoinstruction is being assembled into\n- `args`: array of evaluated pseudoinstruction arguments in the order they appear in the assembly syntax, where `number` is used for expressions that evaluate to a float, `bigint` for those that evaluate to an integer, `string` for simple identifiers (register names) and `null` for those that can't be evaluated (expressions containing undefined labels/forward references)\n- The returned string must be the definition in instruction sequence form\n- The function is allowed to throw any `JS` value that can be converted to a string, which will be displayed in error messages",
"type": "string"
},
"fields": {
Expand Down
24 changes: 7 additions & 17 deletions src/core/capi/arch/riscv.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,13 @@
import { bi_BigIntTofloat, bi_BigIntTodouble } from "@/core/utils/bigint.mjs";

function isInt(val, bits) {
const max = (1n << BigInt(bits - 1)) - 1n;
const min = -(1n << BigInt(bits - 1));
return BigInt(val) >= min && BigInt(val) <= max;
return val === BigInt.asIntN(bits, val);
}

function signExtend(val, bits) {
const mask = (1n << BigInt(bits)) - 1n;
const signBit = 1n << (BigInt(bits) - 1n);
const value = BigInt(val) & mask;
return value & signBit ? value | ~mask : value;
}

function countTrailingZeros(val) {
if (val === 0n) return 64;
function countTrailingZeros(value) {
if (value === 0n) return 64;

let count = 0;
let value = BigInt(val);
while ((value & 1n) === 0n) {
count++;
value >>= 1n;
Expand All @@ -48,7 +38,7 @@ function generateInstructionsImpl(value, instructions, destReg) {
// Handle 32-bit values with LUI+ADDI sequence
if (isInt(value, 32)) {
const hi20 = Number(((value + 0x800n) >> 12n) & 0xfffffn);
const lo12 = Number(signExtend(value, 12));
const lo12 = Number(BigInt.asIntN(12, value));

if (hi20) {
instructions.push(`lui ${destReg}, 0x${hi20.toString(16)}`);
Expand All @@ -63,8 +53,8 @@ function generateInstructionsImpl(value, instructions, destReg) {
}

// Handle larger values (RV64)
const lo12 = Number(signExtend(value, 12));
let remainingValue = value - BigInt(lo12);
const lo12 = BigInt.asIntN(12, value);
let remainingValue = value - lo12;

// Check if shifting can simplify the representation
let shift = 0;
Expand Down Expand Up @@ -103,7 +93,7 @@ function generateInstructionsImpl(value, instructions, destReg) {
export const ARCH = {
generateLoadImmediate(val, destReg) {
const instructions = [];
generateInstructionsImpl(BigInt(val), instructions, destReg);
generateInstructionsImpl(BigInt.asIntN(64, val), instructions, destReg);
return instructions.join(";");
},
toJSNumberD(bigIntValue) {
Expand Down
9 changes: 9 additions & 0 deletions src/core/capi/fp.mts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ export const FP = {
return checkTypeIEEE(sign, exponent, mantissa);
},

/**
* Checks whether a `size` bits value fits in `target` bits
*/
check_int_size(x: bigint | null, size: number, target: number): boolean {
return (
x !== null && BigInt.asIntN(size, x) === BigInt.asIntN(target, x)
);
},

float2bin(f: number): string {
return float2bin(f);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,47 @@ export const snapshot = {};

snapshot[`mips/error/compiler/test_mips_error_compiler_016.s 1`] = `
{
column: 32,
column: 33,
errorText: "Compilation error",
line: 8,
}
`;

snapshot[`mips/error/compiler/test_mips_error_compiler_016.s 2`] = `
'Error: Unterminated string literal
╭─[ assembly:8:32 ]
╭─[ assembly:8:33 ]
8 │ example: .ascii hello world"
───┬─
│ ╰─── While parsing this identifier
│ │
│ ╰── Caused by this
╰─── While parsing this string
╰── Caused by this
───╯
'
`;

snapshot[`mips/error/compiler/test_mips_error_compiler_016.s 3`] = `
"<span style='color:var(--err-red,#a00)'>Error:</span> Unterminated string literal
<span style='color:#949494'>╭─[</span> assembly:8:32 <span style='color:#949494'>]</span>
<span style='color:#949494'>╭─[</span> assembly:8:33 <span style='color:#949494'>]</span>
<span style='color:#949494'>│</span>
<span style='color:#949494'>8 │</span> <span style='color:#b2b2b2'> example: .ascii hello </span><span style='color:var(--err-yellow,#a60)'>world</span><span style='color:var(--err-red,#a00)'>&quot;</span>
<span style='color:#585858'> │</span> <span style='color:var(--err-yellow,#a60)'>───┬─</span><span style='color:var(--err-red,#a00)'>┬</span>
<span style='color:#585858'> │</span> <span style='color:var(--err-yellow,#a60)'>╰───</span> While parsing this <span style='color:var(--err-yellow,#a60)'>identifier</span>
<span style='color:#585858'> │</span> <span style='color:var(--err-red,#a00)'>│</span>
<span style='color:#585858'> │</span> <span style='color:var(--err-red,#a00)'>╰──</span> Caused by this
<span style='color:#949494'>8 │</span> <span style='color:#b2b2b2'> example: .ascii hello world</span><span style='color:var(--err-yellow,#a60)'>&quot;</span>
<span style='color:#585858'> │</span> <span style='color:var(--err-yellow,#a60)'></span><span style='color:var(--err-red,#a00)'>┬</span>
<span style='color:#585858'> │</span> <span style='color:var(--err-yellow,#a60)'>╰───</span> While parsing this <span style='color:var(--err-yellow,#a60)'>string</span>
<span style='color:#585858'> │</span> <span style='color:var(--err-red,#a00)'>│</span>
<span style='color:#585858'> │</span> <span style='color:var(--err-red,#a00)'>╰──</span> Caused by this
<span style='color:#949494'>───╯</span>
"
`;

snapshot[`mips/error/compiler/test_mips_error_compiler_016.s 4`] = `
'Error: Unterminated string literal
╭─[ assembly:8:32 ]
╭─[ assembly:8:33 ]
│
8 │     example:    .ascii hello world"
 │ ───┬─┬
 │ ╰──── While parsing this identifier
 │ │
 │ ╰── Caused by this
8 │     example:    .ascii hello world"
 │ ┬
 │ ╰─── While parsing this string
 │ │
 │ ╰── Caused by this
───╯
'
`;
Loading
Loading