diff --git a/architecture/MIPS32.yml b/architecture/MIPS32.yml index 1fd69738d..d4313d31d 100644 --- a/architecture/MIPS32.yml +++ b/architecture/MIPS32.yml @@ -4379,10 +4379,13 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - if(Field.3.SIZE<=16){addi $rs, $rt, inm;} - else{lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; - add $rs, $rt, $at;} + js: + if(CAPI.FP.check_int_size(args[2], 32, 16)) return "addi $rs, $rt, inm;" + return ` + lui $at, %hi(inm); + ori $at, $at, %lo(inm); + add $rs, $rt, $at; + ` - name: addi help: "" properties: [] @@ -4399,8 +4402,8 @@ pseudoinstructions: - field: val type: imm-signed definition: |- - lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; + lui $at, %hi(val); + ori $at, $at, %lo(val); add $reg1, $reg2, $at; - name: addiu help: "" @@ -4418,8 +4421,8 @@ pseudoinstructions: - field: val type: imm-signed definition: |- - lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; + lui $at, %hi(val); + ori $at, $at, %lo(val); addu $reg1, $reg2, $at; - name: addu help: "" @@ -4437,10 +4440,13 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - if(Field.3.SIZE<=16){addiu $rs, $rt, inm;} - else{lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; - addu $rs, $rt, $at;} + js: + if(CAPI.FP.check_int_size(args[2], 32, 16)) return "addiu $rs, $rt, inm;" + return ` + lui $at, %hi(inm); + ori $at, $at, %lo(inm); + addu $rs, $rt, $at; + ` - name: and help: "" properties: [] @@ -4457,10 +4463,13 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - if(Field.3.SIZE<=16){andi $rs, $rt, inm;} - else{lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; - and $rs, $rt, $at;} + js: + if(CAPI.FP.check_int_size(args[2], 32, 16)) return "andi $rs, $rt, inm;" + return ` + lui $at, %hi(inm); + ori $at, $at, %lo(inm); + and $rs, $rt, $at; + ` - name: andi help: "" properties: [] @@ -4477,8 +4486,8 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; + lui $at, %hi(val); + ori $at, $at, %lo(val); and $rs, $rt, $at; - name: b help: "" @@ -4955,10 +4964,13 @@ pseudoinstructions: - field: addr type: imm-signed definition: |- - if(Field.2.SIZE<=16){addi $rd, $zero, addr;} - else{lui $at, Field.2.(31,16).int; - ori $at, $at, Field.2.(15,0).int; - add $rd, $zero, $at;} + js: + if(CAPI.FP.check_int_size(args[1], 32, 16)) return "addi $rd, $zero, addr;" + return ` + lui $at, %hi(addr); + ori $at, $at, %lo(addr); + add $rd, $zero, $at; + ` - name: lb help: "" properties: [] @@ -4971,10 +4983,13 @@ pseudoinstructions: - field: addr type: imm-signed definition: |- - if(Field.2.SIZE<=16){lb $rd, addr($zero);} - else{lui $at, Field.2.(31,16).int; - ori $at, $at, Field.2.(15,0).int; - lb $rd, 0($at);} + js: + if(CAPI.FP.check_int_size(args[1], 32, 16)) return "lb $rd, addr($zero);" + return ` + lui $at, %hi(addr); + ori $at, $at, %lo(addr); + lb $rd, 0($at); + ` - name: lbu help: "" properties: [] @@ -4987,10 +5002,13 @@ pseudoinstructions: - field: addr type: imm-signed definition: |- - if(Field.2.SIZE<=16){lbu $rd, addr($zero);} - else{lui $at, Field.2.(31,16).int; - ori $at, $at, Field.2.(15,0).int; - lbu $rd, 0($at);} + js: + if(CAPI.FP.check_int_size(args[1], 32, 16)) return "lbu $rd, addr($zero);" + return ` + lui $at, %hi(addr); + ori $at, $at, %lo(addr); + lbu $rd, 0($at); + ` - name: lh help: "" properties: [] @@ -5003,10 +5021,13 @@ pseudoinstructions: - field: addr type: imm-signed definition: |- - if(Field.2.SIZE<=16){lh $rd, addr($zero);} - else{lui $at, Field.2.(31,16).int; - ori $at, $at, Field.2.(15,0).int; - lh $rd, 0($at);} + js: + if(CAPI.FP.check_int_size(args[1], 32, 16)) return "lh $rd, addr($zero);" + return ` + lui $at, %hi(addr); + ori $at, $at, %lo(addr); + lh $rd, 0($at); + ` - name: lhu help: "" properties: [] @@ -5019,10 +5040,13 @@ pseudoinstructions: - field: addr type: imm-signed definition: |- - if(Field.2.SIZE<=16){lhu $rd, addr($zero);} - else{lui $at, Field.2.(31,16).int; - ori $at, $at, Field.2.(15,0).int; - lhu $rd, 0($at);} + js: + if(CAPI.FP.check_int_size(args[1], 32, 16)) return "lhu $rd, addr($zero);" + return ` + lui $at, %hi(addr); + ori $at, $at, %lo(addr); + lhu $rd, 0($at); + ` - name: li help: "" properties: [] @@ -5035,13 +5059,13 @@ pseudoinstructions: - field: val type: imm-signed definition: |- - no_ret_op{tmp=Field.2.(31,0).int; - tmp_low=tmp&0x0000FFFF; - tmp_hi=tmp>>>16}; - if(tmp_hi === 0){addi $rd, $zero, op{tmp_low};} - else{lui $at, op{tmp_hi}; - ori $at, $at, op{tmp_low}; - add $rd, $zero, $at;} + js: + if(args[1] !== null && (Number(args[1]) >>> 16) === 0) return `addi $rd, $zero, ${args[1]}` + return ` + lui $at, %hi(val); + ori $at, $at, %lo(val); + add $rd, $zero, $at; + ` - name: li.d help: "" properties: [] @@ -5054,24 +5078,24 @@ pseudoinstructions: - field: val type: imm-signed definition: |- - no_ret_op{ - tmp0=Field.2.(63,32).double; - tmp_low0=tmp0&0x0000FFFF; - tmp_hi0=tmp0>>>16; - tmp1=Field.2.(31,0).double; - tmp_low1=tmp1&0x0000FFFF; - tmp_hi1=tmp1>>>16; - tmp_reg=reg_name{1}; - regNumber=parseInt(tmp_reg.substring(2), 10); - reg0="f" + regNumber; - reg1="f" + (regNumber + 1); - }; - lui $at, op{tmp_hi1}; - ori $at, $at, op{tmp_low1}; - mtc1 $at, $op{reg1}; - lui $at, op{tmp_hi0}; - ori $at, $at, op{tmp_low0}; - mtc1 $at, $op{reg0}; + js: + let val = args[1]; + if (val === null) throw "Forward references aren't allowed"; + let [low, high] = CAPI.FP.float642uint(Number(val)) + + let reg = args[0]; + let regNumber = parseInt(reg.substring(2), 10); + let reg0 ="f" + regNumber; + let reg1 ="f" + (regNumber + 1); + return ` + lui $at, %hi(${low}); + ori $at, $at, %lo(${low}); + mtc1 $at, $${reg1}; + + lui $at, %hi(${high}); + ori $at, $at, %lo(${high}); + mtc1 $at, $${reg0}; + ` - name: li.s help: "" properties: [] @@ -5084,12 +5108,15 @@ pseudoinstructions: - field: val type: imm-signed definition: |- - no_ret_op{tmp=Field.2.(31,0).float; - tmp_low=tmp&0x0000FFFF; - tmp_hi=tmp>>>16}; - lui $at, op{tmp_hi}; - ori $at, $at, op{tmp_low}; - mtc1 $at, $rd; + js: + let val = args[1]; + if (val === null) throw "Forward references aren't allowed"; + val = CAPI.FP.float322uint(Number(val)) + return ` + lui $at, %hi(${val}); + ori $at, $at, %lo(${val}); + mtc1 $at, $rd; + ` - name: lw help: "" properties: [] @@ -5102,10 +5129,13 @@ pseudoinstructions: - field: addr type: imm-signed definition: |- - if(Field.2.SIZE<=16){lw $rd, addr($zero);} - else{lui $at, Field.2.(31,16).int; - ori $at, $at, Field.2.(15,0).int; - lw $rd, 0($at);} + js: + if(CAPI.FP.check_int_size(args[1], 32, 16)) return "lw $rd, addr($zero);" + return ` + lui $at, %hi(addr); + ori $at, $at, %lo(addr); + lw $rd, 0($at); + ` - name: move help: "" properties: [] @@ -5136,10 +5166,13 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - if(Field.3.SIZE<=16){addi $at, $zero, inm; mul $rs, $rt, $at;} - else{lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; - mul $rs, $rt, $at;} + js: + if(CAPI.FP.check_int_size(args[2], 32, 16)) return "addi $at, $zero, inm; mul $rs, $rt, $at;" + return ` + lui $at, %hi(inm); + ori $at, $at, %lo(inm); + mul $rs, $rt, $at; + ` - name: nor help: "" properties: [] @@ -5156,10 +5189,13 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - if(Field.3.SIZE<=16){addi $at, $zero, inm; nor $rs, $rt, $at;} - else{lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; - nor $rs, $rt, $at;} + js: + if(CAPI.FP.check_int_size(args[2], 32, 16)) return "addi $at, $zero, inm; nor $rs, $rt, $at;" + return ` + lui $at, %hi(inm); + ori $at, $at, %lo(inm); + nor $rs, $rt, $at; + ` - name: or help: "" properties: [] @@ -5176,10 +5212,13 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - if(Field.3.SIZE<=16){ori $rs, $rt, inm;} - else{lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; - or $rs, $rt, $at;} + js: + if(CAPI.FP.check_int_size(args[2], 32, 16)) return "ori $rs, $rt, inm;" + return ` + lui $at, %hi(inm); + ori $at, $at, %lo(inm); + or $rs, $rt, $at; + ` - name: ori help: "" properties: [] @@ -5196,8 +5235,8 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; + lui $at, %hi(inm); + ori $at, $at, %lo(inm); or $rs, $rt, $at; - name: rem help: "" @@ -5297,10 +5336,13 @@ pseudoinstructions: - field: addr type: imm-signed definition: |- - if(Field.2.SIZE<=16){sb $rd, addr($zero);} - else{lui $at, Field.2.(31,16).int; - ori $at, $at, Field.2.(15,0).int; - sb $rd, 0($at);} + js: + if(CAPI.FP.check_int_size(args[1], 32, 16)) return "sb $rd, addr($zero);" + return ` + lui $at, %hi(addr); + ori $at, $at, %lo(addr); + sb $rd, 0($at); + ` - name: sh help: "" properties: [] @@ -5313,10 +5355,13 @@ pseudoinstructions: - field: addr type: imm-signed definition: |- - if(Field.2.SIZE<=16){sh $rd, addr($zero);} - else{lui $at, Field.2.(31,16).int; - ori $at, $at, Field.2.(15,0).int; - sh $rd, 0($at);} + js: + if(CAPI.FP.check_int_size(args[1], 32, 16)) return "sh $rd, addr($zero);" + return ` + lui $at, %hi(addr); + ori $at, $at, %lo(addr); + sh $rd, 0($at); + ` - name: sub help: "" properties: [] @@ -5333,10 +5378,13 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - if(Field.3.SIZE<=16){addi $at, $zero, inm; sub $rs, $rt, $at;} - else{lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; - sub $rs, $rt, $at;} + js: + if(CAPI.FP.check_int_size(args[2], 32, 16)) return "addi $at, $zero, inm; sub $rs, $rt, $at;" + return ` + lui $at, %hi(inm); + ori $at, $at, %lo(inm); + sub $rs, $rt, $at; + ` - name: subu help: "" properties: [] @@ -5353,10 +5401,13 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - if(Field.3.SIZE<=16){addi $at, $zero, inm; subu $rs, $rt, $at;} - else{lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; - subu $rs, $rt, $at;} + js: + if(CAPI.FP.check_int_size(args[2], 32, 16)) return "addi $at, $zero, inm; subu $rs, $rt, $at;" + return ` + lui $at, %hi(inm); + ori $at, $at, %lo(inm); + subu $rs, $rt, $at; + ` - name: sw help: "" properties: [] @@ -5369,10 +5420,13 @@ pseudoinstructions: - field: addr type: imm-signed definition: |- - if(Field.2.SIZE<=16){sw $rd, addr($zero);} - else{lui $at, Field.2.(31,16).int; - ori $at, $at, Field.2.(15,0).int; - sw $rd, 0($at);} + js: + if(CAPI.FP.check_int_size(args[1], 32, 16)) return "sw $rd, addr($zero);" + return ` + lui $at, %hi(addr); + ori $at, $at, %lo(addr); + sw $rd, 0($at); + ` - name: xor help: "" properties: [] @@ -5389,10 +5443,13 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - if(Field.3.SIZE<=16){xori $rs, $rt, inm;} - else{lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; - xor $rs, $rt, $at;} + js: + if(CAPI.FP.check_int_size(args[2], 32, 16)) return "xori $rs, $rt, inm;" + return ` + lui $at, %hi(inm); + ori $at, $at, %lo(inm); + xor $rs, $rt, $at; + ` - name: xori help: "" properties: [] @@ -5409,8 +5466,8 @@ pseudoinstructions: - field: inm type: imm-signed definition: |- - lui $at, Field.3.(31,16).int; - ori $at, $at, Field.3.(15,0).int; + lui $at, %hi(inm); + ori $at, $at, %lo(inm); xor $rs, $rt, $at; directives: - name: .data @@ -5453,6 +5510,16 @@ directives: action: align size: null +modifiers: + hi: + lower_signed: false + output_signed: false + range: [16, 32] + lo: + lower_signed: false + output_signed: false + range: [0, 16] + memory_layout: text: start: 0x00000000 diff --git a/architecture/RISCV/RV32IMFD.yml b/architecture/RISCV/RV32IMFD.yml index 90dca4e80..6f95db131 100644 --- a/architecture/RISCV/RV32IMFD.yml +++ b/architecture/RISCV/RV32IMFD.yml @@ -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: @@ -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 diff --git a/architecture/RISCV/RV64IMFD.yml b/architecture/RISCV/RV64IMFD.yml index 32af4ab14..61ed4f3a5 100644 --- a/architecture/RISCV/RV64IMFD.yml +++ b/architecture/RISCV/RV64IMFD.yml @@ -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 @@ -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: @@ -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: diff --git a/architecture/RISCV/SRV32.yml b/architecture/RISCV/SRV32.yml index cb48e05e8..89a8c23ca 100644 --- a/architecture/RISCV/SRV32.yml +++ b/architecture/RISCV/SRV32.yml @@ -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 @@ -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 @@ -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 diff --git a/architecture/RISCV/SRV64.yml b/architecture/RISCV/SRV64.yml index 16d4ad471..e55548982 100644 --- a/architecture/RISCV/SRV64.yml +++ b/architecture/RISCV/SRV64.yml @@ -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 @@ -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 @@ -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 diff --git a/creator-assembler b/creator-assembler index 75c620cbc..4dfb758e4 160000 --- a/creator-assembler +++ b/creator-assembler @@ -1 +1 @@ -Subproject commit 75c620cbc7c1661310365118d8a8bf8432e22b33 +Subproject commit 4dfb758e4635c3618e42075231b32f40a6dbc1dc diff --git a/docs/schema/architecture.json b/docs/schema/architecture.json index 192fc5bdb..80d95cc11 100644 --- a/docs/schema/architecture.json +++ b/docs/schema/architecture.json @@ -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) => 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": { diff --git a/src/core/capi/arch/riscv.mjs b/src/core/capi/arch/riscv.mjs index 3b10f1114..83b736e09 100644 --- a/src/core/capi/arch/riscv.mjs +++ b/src/core/capi/arch/riscv.mjs @@ -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; @@ -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)}`); @@ -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; @@ -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) { diff --git a/src/core/capi/fp.mts b/src/core/capi/fp.mts index d95c58c5a..7aa7c8bc5 100644 --- a/src/core/capi/fp.mts +++ b/src/core/capi/fp.mts @@ -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); }, diff --git a/tests/arch/__snapshots__/mips/error/compiler/test_mips_error_compiler_016.s.snap b/tests/arch/__snapshots__/mips/error/compiler/test_mips_error_compiler_016.s.snap index 9f9d44ae0..b51246254 100644 --- a/tests/arch/__snapshots__/mips/error/compiler/test_mips_error_compiler_016.s.snap +++ b/tests/arch/__snapshots__/mips/error/compiler/test_mips_error_compiler_016.s.snap @@ -2,7 +2,7 @@ export const snapshot = {}; snapshot[`mips/error/compiler/test_mips_error_compiler_016.s 1`] = ` { - column: 32, + column: 33, errorText: "Compilation error", line: 8, } @@ -10,39 +10,39 @@ snapshot[`mips/error/compiler/test_mips_error_compiler_016.s 1`] = ` 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`] = ` "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 ───╯ " `; 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 ───╯ ' `; diff --git a/tests/arch/__snapshots__/riscv/error/compiler/test_riscv_error_compiler_016.s.snap b/tests/arch/__snapshots__/riscv/error/compiler/test_riscv_error_compiler_016.s.snap index cffc1ed27..fdd5d2211 100644 --- a/tests/arch/__snapshots__/riscv/error/compiler/test_riscv_error_compiler_016.s.snap +++ b/tests/arch/__snapshots__/riscv/error/compiler/test_riscv_error_compiler_016.s.snap @@ -2,7 +2,7 @@ export const snapshot = {}; snapshot[`riscv/error/compiler/test_riscv_error_compiler_016.s 1`] = ` { - column: 33, + column: 34, errorText: "Compilation error", line: 8, } @@ -10,39 +10,39 @@ snapshot[`riscv/error/compiler/test_riscv_error_compiler_016.s 1`] = ` snapshot[`riscv/error/compiler/test_riscv_error_compiler_016.s 2`] = ` 'Error: Unterminated string literal - ╭─[ assembly:8:33 ] + ╭─[ assembly:8:34 ] │ 8 │ example: .string hello world" - │ ───┬─┬ - │ ╰──── While parsing this identifier - │ │ - │ ╰── Caused by this + │ ┬┬ + │ ╰─── While parsing this string + │ │ + │ ╰── Caused by this ───╯ ' `; snapshot[`riscv/error/compiler/test_riscv_error_compiler_016.s 3`] = ` "Error: Unterminated string literal - ╭─[ assembly:8:33 ] + ╭─[ assembly:8:34 ] - 8 │ example: .string hello world" - ───┬─ - ╰──── While parsing this identifier - - ╰── Caused by this + 8 │ example: .string hello world" + + ╰─── While parsing this string + + ╰── Caused by this ───╯ " `; snapshot[`riscv/error/compiler/test_riscv_error_compiler_016.s 4`] = ` 'Error: Unterminated string literal - ╭─[ assembly:8:33 ] + ╭─[ assembly:8:34 ] │ - 8 │     example:    .string hello world" -  │ ───┬─┬ -  │ ╰──── While parsing this identifier -  │ │ -  │ ╰── Caused by this + 8 │     example:    .string hello world" +  │ ┬┬ +  │ ╰─── While parsing this string +  │ │ +  │ ╰── Caused by this ───╯ ' `;