nice size optimizations
This commit is contained in:
@@ -18,10 +18,14 @@ function trapout(msg) {
|
|||||||
|
|
||||||
# helper functions
|
# helper functions
|
||||||
|
|
||||||
|
function uint32(val) {
|
||||||
|
val = int(val) % 4294967296
|
||||||
|
return (val < 0) ? (val + 4294967296) : val
|
||||||
|
}
|
||||||
|
|
||||||
function setreg(idx, val) {
|
function setreg(idx, val) {
|
||||||
if(idx > 0) {
|
if(idx > 0) {
|
||||||
val = int(val) % 4294967296
|
val = uint32(val)
|
||||||
if(val < 0) val += 4294967296
|
|
||||||
REG[idx] = (val >= 2147483648) ? (val - 4294967296) : val
|
REG[idx] = (val >= 2147483648) ? (val - 4294967296) : val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,78 +45,54 @@ function ord(c, b) {
|
|||||||
return int(TGL_ORD[c])
|
return int(TGL_ORD[c])
|
||||||
}
|
}
|
||||||
|
|
||||||
function bw_and(a, b, v, r) {
|
function bw_op(a, b, op, v, r) {
|
||||||
v = 1; r = 0; a = int(a); b = int(b)
|
v = 1; r = 0; a = uint32(a); b = uint32(b)
|
||||||
if(a < 0) a += 4294967296
|
|
||||||
if(b < 0) b += 4294967296
|
|
||||||
while(a > 0 || b > 0) {
|
while(a > 0 || b > 0) {
|
||||||
if((a%2) == 1 && (b%2) == 1) r += v
|
if(op == "&" && (a%2) == 1 && (b%2) == 1) r += v
|
||||||
|
else if(op == "|" && ((a%2) == 1 || (b%2) == 1)) r += v
|
||||||
|
else if(op == "^" && (a%2) != (b%2)) r += v
|
||||||
a = int(a/2); b = int(b/2); v *= 2
|
a = int(a/2); b = int(b/2); v *= 2
|
||||||
}
|
}
|
||||||
return int(r)
|
return int(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
function bw_or(a, b, v, r) {
|
function bw_and(a, b) {return bw_op(a, b, "&")}
|
||||||
v = 1; r = 0; a = int(a); b = int(b)
|
function bw_or(a, b) {return bw_op(a, b, "|")}
|
||||||
if(a < 0) a += 4294967296
|
function bw_xor(a, b) {return bw_op(a, b, "^")}
|
||||||
if(b < 0) b += 4294967296
|
|
||||||
while(a > 0 || b > 0) {
|
function read_mem(addr, bytes, signed, i, val, max_val) {
|
||||||
if((a%2) == 1 || (b%2) == 1) r += v
|
addr = uint32(addr)
|
||||||
a = int(a/2); b = int(b/2); v *= 2
|
val = 0
|
||||||
|
for(i=0; i<bytes; i++) val += MEM[(addr+i)%4294967296] * (256^i)
|
||||||
|
if(signed) {
|
||||||
|
max_val = 256^bytes
|
||||||
|
if(val >= max_val/2) val -= max_val
|
||||||
}
|
}
|
||||||
return int(r)
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
function bw_xor(a, b, v, r) {
|
function write_mem(addr, val, bytes, i) {
|
||||||
v = 1; r = 0; a = int(a); b = int(b)
|
addr = uint32(addr)
|
||||||
if(a < 0) a += 4294967296
|
val = uint32(val)
|
||||||
if(b < 0) b += 4294967296
|
for(i=0; i<bytes; i++) MEM[(addr+i)%4294967296] = int(val / (256^i)) % 256
|
||||||
while(a > 0 || b > 0) {
|
|
||||||
if((a%2) != (b%2)) r += v
|
|
||||||
a = int(a/2); b = int(b/2); v *= 2
|
|
||||||
}
|
|
||||||
return int(r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_word(addr, val) {
|
function read_word(addr) {return read_mem(addr, 4, 1)}
|
||||||
addr = int(addr) % 4294967296
|
function write_word(addr, val) {write_mem(addr, val, 4)}
|
||||||
if(addr < 0) addr += 4294967296
|
|
||||||
val = MEM[addr] + MEM[(addr+1)%4294967296]*256 + MEM[(addr+2)%4294967296]*65536 + MEM[(addr+3)%4294967296]*16777216
|
|
||||||
return (val >= 2147483648) ? (val - 4294967296) : val
|
|
||||||
}
|
|
||||||
|
|
||||||
function write_word(addr, val) {
|
|
||||||
addr = int(addr) % 4294967296
|
|
||||||
if(addr < 0) addr += 4294967296
|
|
||||||
val = int(val) % 4294967296
|
|
||||||
if(val < 0) val += 4294967296
|
|
||||||
MEM[addr] = val % 256
|
|
||||||
MEM[(addr+1)%4294967296] = int(val/256) % 256
|
|
||||||
MEM[(addr+2)%4294967296] = int(val/65536) % 256
|
|
||||||
MEM[(addr+3)%4294967296] = int(val/16777216) % 256
|
|
||||||
}
|
|
||||||
|
|
||||||
# syscall emulation
|
# syscall emulation
|
||||||
|
|
||||||
function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, addr) {
|
function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf) {
|
||||||
if(callnum == 63) { # sys_read
|
if(callnum == 63) { # sys_read
|
||||||
if(a0 == 0) {
|
if(a0 == 0) {
|
||||||
getline buf < "/dev/tty"
|
getline buf < "/dev/tty"
|
||||||
l = length(buf)
|
l = length(buf); if(l > a2) l = a2
|
||||||
if(l > a2) l = a2
|
for(i=0; i<l; i++) MEM[uint32(a1 + i)] = ord(substr(buf, i+1, 1))
|
||||||
for(i=0;i<l;i++) {
|
|
||||||
addr = (a1 + i) % 4294967296
|
|
||||||
MEM[addr] = ord(substr(buf, i+1, 1))
|
|
||||||
}
|
|
||||||
setreg(10, i)
|
setreg(10, i)
|
||||||
}
|
}
|
||||||
} else if(callnum == 64) { # sys_write
|
} else if(callnum == 64) { # sys_write
|
||||||
if(a0 == 1 || a0 == 2) {
|
if(a0 == 1 || a0 == 2) {
|
||||||
for(i=0;i<a2;i++) {
|
for(i=0; i<a2; i++) printf("%c", MEM[uint32(a1 + i)])
|
||||||
addr = (a1 + i) % 4294967296
|
|
||||||
buf = int(MEM[addr])
|
|
||||||
printf("%c", buf)
|
|
||||||
}
|
|
||||||
setreg(10, i)
|
setreg(10, i)
|
||||||
}
|
}
|
||||||
} else if(callnum == 93) exit(a0) # sys_exit
|
} else if(callnum == 93) exit(a0) # sys_exit
|
||||||
@@ -122,10 +102,8 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, addr) {
|
|||||||
# instruction type executors
|
# instruction type executors
|
||||||
|
|
||||||
function amach_reg_arith(f3, f7, rd, rs1, rs2, r1, r2, ur1, ur2, shamt) {
|
function amach_reg_arith(f3, f7, rd, rs1, rs2, r1, r2, ur1, ur2, shamt) {
|
||||||
r1 = getreg(rs1)
|
r1 = getreg(rs1); r2 = getreg(rs2)
|
||||||
r2 = getreg(rs2)
|
ur1 = uint32(r1); ur2 = uint32(r2)
|
||||||
ur1 = (r1 >= 0) ? r1 : (r1 + 4294967296)
|
|
||||||
ur2 = (r2 >= 0) ? r2 : (r2 + 4294967296)
|
|
||||||
shamt = ur2 % 32
|
shamt = ur2 % 32
|
||||||
|
|
||||||
if(f3 == 0 && f7 == 0) setreg(rd, r1 + r2)
|
if(f3 == 0 && f7 == 0) setreg(rd, r1 + r2)
|
||||||
@@ -149,31 +127,15 @@ function amach_reg_arith(f3, f7, rd, rs1, rs2, r1, r2, ur1, ur2, shamt) {
|
|||||||
else trapout(sprintf("Illegal instruction at 0x%X", pc-4))
|
else trapout(sprintf("Illegal instruction at 0x%X", pc-4))
|
||||||
}
|
}
|
||||||
|
|
||||||
function amach_store(f3, rs1, rs2, immval, r1, r2, base) {
|
function amach_store(f3, rs1, rs2, immval, r1, r2) {
|
||||||
r1 = getreg(rs1)
|
r1 = getreg(rs1); r2 = getreg(rs2)
|
||||||
r2 = getreg(rs2)
|
if(f3 >= 0 && f3 <= 2) write_mem(r1 + immval, r2, 2^f3)
|
||||||
if(r2 < 0) r2 += 4294967296
|
|
||||||
base = (r1 + immval) % 4294967296
|
|
||||||
if(base < 0) base += 4294967296
|
|
||||||
if(f3 == 0) MEM[base] = r2 % 256
|
|
||||||
else if(f3 == 1) {
|
|
||||||
MEM[base] = r2 % 256
|
|
||||||
MEM[(base + 1)%4294967296] = int(r2/256) % 256
|
|
||||||
}
|
|
||||||
else if(f3 == 2) {
|
|
||||||
MEM[base] = r2 % 256
|
|
||||||
MEM[(base + 1)%4294967296] = int(r2/256) % 256
|
|
||||||
MEM[(base + 2)%4294967296] = int(r2/65536) % 256
|
|
||||||
MEM[(base + 3)%4294967296] = int(r2/16777216) % 256
|
|
||||||
}
|
|
||||||
else trapout(sprintf("Illegal instruction at 0x%X", pc-4))
|
else trapout(sprintf("Illegal instruction at 0x%X", pc-4))
|
||||||
}
|
}
|
||||||
|
|
||||||
function amach_branch(f3, rs1, rs2, immval, r1, r2, ur1, ur2, taken) {
|
function amach_branch(f3, rs1, rs2, immval, r1, r2, ur1, ur2, taken) {
|
||||||
r1 = getreg(rs1)
|
r1 = getreg(rs1); r2 = getreg(rs2)
|
||||||
r2 = getreg(rs2)
|
ur1 = uint32(r1); ur2 = uint32(r2)
|
||||||
ur1 = (r1 >= 0) ? r1 : (r1 + 4294967296)
|
|
||||||
ur2 = (r2 >= 0) ? r2 : (r2 + 4294967296)
|
|
||||||
taken = 0
|
taken = 0
|
||||||
if(f3 == 0) taken = (r1 == r2)
|
if(f3 == 0) taken = (r1 == r2)
|
||||||
else if(f3 == 1) taken = (r1 != r2)
|
else if(f3 == 1) taken = (r1 != r2)
|
||||||
@@ -185,27 +147,12 @@ function amach_branch(f3, rs1, rs2, immval, r1, r2, ur1, ur2, taken) {
|
|||||||
pc += (taken ? immval : 4)
|
pc += (taken ? immval : 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
function amach_imm(opcode, f3, rd, rs1, immval, r1, ur1, base, shamt, val) {
|
function amach_imm(opcode, f3, rd, rs1, immval, r1, ur1, shamt) {
|
||||||
r1 = getreg(rs1)
|
r1 = getreg(rs1); ur1 = uint32(r1)
|
||||||
ur1 = (r1 >= 0) ? r1 : (r1 + 4294967296)
|
|
||||||
if(opcode == 3) { # load
|
if(opcode == 3) { # load
|
||||||
base = (r1 + immval) % 4294967296
|
if(f3 == 0 || f3 == 1 || f3 == 2 || f3 == 4 || f3 == 5) {
|
||||||
if(base < 0) base += 4294967296
|
setreg(rd, read_mem(r1 + immval, 2^(f3 % 4), f3 < 4))
|
||||||
if(f3 == 0) { # lb
|
} else trapout(sprintf("Illegal instruction at 0x%X", pc-4))
|
||||||
val = MEM[base]
|
|
||||||
setreg(rd, (val >= 128) ? (val - 256) : val)
|
|
||||||
}
|
|
||||||
else if(f3 == 1) { # lh
|
|
||||||
val = MEM[base] + MEM[(base+1)%4294967296]*256
|
|
||||||
setreg(rd, (val >= 32768) ? (val - 65536) : val)
|
|
||||||
}
|
|
||||||
else if(f3 == 2) {
|
|
||||||
val = MEM[base] + MEM[(base+1)%4294967296]*256 + MEM[(base+2)%4294967296]*65536 + MEM[(base+3)%4294967296]*16777216
|
|
||||||
setreg(rd, val)
|
|
||||||
}
|
|
||||||
else if(f3 == 4) setreg(rd, MEM[base]) # lbu
|
|
||||||
else if(f3 == 5) setreg(rd, MEM[base] + MEM[(base+1)%4294967296]*256) # lhu
|
|
||||||
else trapout(sprintf("Illegal instruction at 0x%X", pc-4))
|
|
||||||
} else if(opcode == 19) { # 0x13, immediate arithmetic
|
} else if(opcode == 19) { # 0x13, immediate arithmetic
|
||||||
shamt = bw_and(immval, 31)
|
shamt = bw_and(immval, 31)
|
||||||
if(f3 == 0) setreg(rd, r1 + immval)
|
if(f3 == 0) setreg(rd, r1 + immval)
|
||||||
@@ -229,12 +176,11 @@ function amach_imm(opcode, f3, rd, rs1, immval, r1, ur1, base, shamt, val) {
|
|||||||
|
|
||||||
# A-extension
|
# A-extension
|
||||||
function amach_atomic(f3, f5, aq, rl, rd, rs1, rs2, r1, r2, val, uval, ur2) {
|
function amach_atomic(f3, f5, aq, rl, rd, rs1, rs2, r1, r2, val, uval, ur2) {
|
||||||
r1 = getreg(rs1)
|
r1 = getreg(rs1); r2 = getreg(rs2)
|
||||||
r2 = getreg(rs2)
|
ur2 = uint32(r2)
|
||||||
ur2 = (r2 >= 0) ? r2 : (r2 + 4294967296)
|
|
||||||
if(f3 == 2) {
|
if(f3 == 2) {
|
||||||
val = read_word(r1)
|
val = read_word(r1)
|
||||||
uval = (val >= 0) ? val : (val + 4294967296)
|
uval = uint32(val)
|
||||||
if(f5 == 0) { # amoadd.w
|
if(f5 == 0) { # amoadd.w
|
||||||
setreg(rd, val)
|
setreg(rd, val)
|
||||||
write_word(r1, val + r2)
|
write_word(r1, val + r2)
|
||||||
@@ -286,134 +232,110 @@ function amach_comp(instr, op, f3, b12, r11_7, r9_7, r6_2, r4_2, shamt, imm, ba
|
|||||||
r4_2 = (r6_2 % 8) + 8
|
r4_2 = (r6_2 % 8) + 8
|
||||||
shamt = r6_2 + b12 * 32
|
shamt = r6_2 + b12 * 32
|
||||||
|
|
||||||
if (op == 0) {
|
if(op == 0) {
|
||||||
if (f3 == 0) { # C.ADDI4SPN
|
if(f3 == 0) { # C.ADDI4SPN
|
||||||
imm = (r11_7 % 16) * 64 + (int(r11_7 / 16) + b12 * 2) * 16 + (int(r6_2 / 8) % 2) * 8 + (int(r6_2 / 16) % 2) * 4
|
imm = (r11_7 % 16) * 64 + (int(r11_7 / 16) + b12 * 2) * 16 + (int(r6_2 / 8) % 2) * 8 + (int(r6_2 / 16) % 2) * 4
|
||||||
if (imm == 0) trapout(sprintf("Illegal instruction C.ADDI4SPN at 0x%X", pc-2))
|
if(imm == 0) trapout(sprintf("Illegal instruction C.ADDI4SPN at 0x%X", pc-2))
|
||||||
setreg(r4_2, getreg(2) + imm)
|
setreg(r4_2, getreg(2) + imm)
|
||||||
} else if (f3 == 2) { # C.LW
|
} else if(f3 == 2) { # C.LW
|
||||||
imm = (int(r6_2 / 8) % 2) * 64 + (int(r11_7 / 8) % 4) * 8 + b12 * 32 + (int(r6_2 / 16) % 2) * 4
|
imm = (int(r6_2 / 8) % 2) * 64 + (int(r11_7 / 8) % 4) * 8 + b12 * 32 + (int(r6_2 / 16) % 2) * 4
|
||||||
base = (getreg(r9_7) + imm) % 4294967296
|
setreg(r4_2, read_mem(getreg(r9_7) + imm, 4, 1))
|
||||||
if (base < 0) base += 4294967296
|
} else if(f3 == 6) { # C.SW
|
||||||
val = MEM[base] + MEM[(base+1)%4294967296]*256 + MEM[(base+2)%4294967296]*65536 + MEM[(base+3)%4294967296]*16777216
|
|
||||||
setreg(r4_2, val)
|
|
||||||
} else if (f3 == 6) { # C.SW
|
|
||||||
imm = (int(r6_2 / 8) % 2) * 64 + (int(r11_7 / 8) % 4) * 8 + b12 * 32 + (int(r6_2 / 16) % 2) * 4
|
imm = (int(r6_2 / 8) % 2) * 64 + (int(r11_7 / 8) % 4) * 8 + b12 * 32 + (int(r6_2 / 16) % 2) * 4
|
||||||
base = (getreg(r9_7) + imm) % 4294967296
|
write_mem(getreg(r9_7) + imm, getreg(r4_2), 4)
|
||||||
if (base < 0) base += 4294967296
|
|
||||||
val = getreg(r4_2)
|
|
||||||
if (val < 0) val += 4294967296
|
|
||||||
MEM[base] = val % 256
|
|
||||||
MEM[(base+1)%4294967296] = int(val/256) % 256
|
|
||||||
MEM[(base+2)%4294967296] = int(val/65536) % 256
|
|
||||||
MEM[(base+3)%4294967296] = int(val/16777216) % 256
|
|
||||||
} else trapout(sprintf("Illegal instruction at 0x%X", pc-2))
|
} else trapout(sprintf("Illegal instruction at 0x%X", pc-2))
|
||||||
} else if (op == 1) {
|
} else if(op == 1) {
|
||||||
if (f3 == 0) { # C.NOP / C.ADDI
|
if(f3 == 0) { # C.NOP / C.ADDI
|
||||||
imm = r6_2 + b12 * 32
|
imm = r6_2 + b12 * 32
|
||||||
if (imm >= 32) imm -= 64
|
if(imm >= 32) imm -= 64
|
||||||
setreg(r11_7, getreg(r11_7) + imm)
|
setreg(r11_7, getreg(r11_7) + imm)
|
||||||
} else if (f3 == 1 || f3 == 5) { # C.JAL / C.J
|
} else if(f3 == 1 || f3 == 5) { # C.JAL / C.J
|
||||||
imm = b12 * 2048 + (int(r11_7 / 2) % 2) * 1024 + (int(r11_7 / 4) % 4) * 256 + (int(r6_2 / 16) % 2) * 128 + (r11_7 % 2) * 64 + (r6_2 % 2) * 32 + (int(r11_7 / 16)) * 16 + (int(r6_2 / 2) % 8) * 2
|
imm = b12 * 2048 + (int(r11_7 / 2) % 2) * 1024 + (int(r11_7 / 4) % 4) * 256 + (int(r6_2 / 16) % 2) * 128 + (r11_7 % 2) * 64 + (r6_2 % 2) * 32 + (int(r11_7 / 16)) * 16 + (int(r6_2 / 2) % 8) * 2
|
||||||
if (imm >= 2048) imm -= 4096
|
if(imm >= 2048) imm -= 4096
|
||||||
if (f3 == 1) setreg(1, pc)
|
if(f3 == 1) setreg(1, pc)
|
||||||
pc = (pc - 2) + imm
|
pc = (pc - 2) + imm
|
||||||
} else if (f3 == 2) { # C.LI
|
} else if(f3 == 2) { # C.LI
|
||||||
imm = r6_2 + b12 * 32
|
imm = r6_2 + b12 * 32
|
||||||
if (imm >= 32) imm -= 64
|
if(imm >= 32) imm -= 64
|
||||||
setreg(r11_7, imm)
|
setreg(r11_7, imm)
|
||||||
} else if (f3 == 3) { # C.ADDI16SP / C.LUI
|
} else if(f3 == 3) { # C.ADDI16SP / C.LUI
|
||||||
if (r11_7 == 2) { # C.ADDI16SP
|
if(r11_7 == 2) { # C.ADDI16SP
|
||||||
imm = b12 * 512 + (int(r6_2 / 2) % 4) * 128 + (int(r6_2 / 8) % 2) * 64 + (r6_2 % 2) * 32 + (int(r6_2 / 16) % 2) * 16
|
imm = b12 * 512 + (int(r6_2 / 2) % 4) * 128 + (int(r6_2 / 8) % 2) * 64 + (r6_2 % 2) * 32 + (int(r6_2 / 16) % 2) * 16
|
||||||
if (imm >= 512) imm -= 1024
|
if(imm >= 512) imm -= 1024
|
||||||
if (imm == 0) trapout(sprintf("Illegal instruction C.ADDI16SP at 0x%X", pc-2))
|
if(imm == 0) trapout(sprintf("Illegal instruction C.ADDI16SP at 0x%X", pc-2))
|
||||||
setreg(2, getreg(2) + imm)
|
setreg(2, getreg(2) + imm)
|
||||||
} else if (r11_7 != 0) { # C.LUI
|
} else if(r11_7 != 0) { # C.LUI
|
||||||
imm = r6_2 + b12 * 32
|
imm = r6_2 + b12 * 32
|
||||||
if (imm >= 32) imm -= 64
|
if(imm >= 32) imm -= 64
|
||||||
imm = imm * 4096
|
imm = imm * 4096
|
||||||
if (imm == 0) trapout(sprintf("Illegal instruction C.LUI at 0x%X", pc-2))
|
if(imm == 0) trapout(sprintf("Illegal instruction C.LUI at 0x%X", pc-2))
|
||||||
setreg(r11_7, imm)
|
setreg(r11_7, imm)
|
||||||
}
|
}
|
||||||
} else if (f3 == 4) {
|
} else if(f3 == 4) {
|
||||||
val = int(r11_7 / 8) % 4
|
val = int(r11_7 / 8) % 4
|
||||||
if (val == 0) { # C.SRLI
|
if(val == 0) { # C.SRLI
|
||||||
if (shamt >= 32) trapout(sprintf("Illegal shift amount %d at 0x%X", shamt, pc-2))
|
if(shamt >= 32) trapout(sprintf("Illegal shift amount %d at 0x%X", shamt, pc-2))
|
||||||
imm = getreg(r9_7)
|
imm = getreg(r9_7)
|
||||||
if (imm < 0) imm += 4294967296
|
if(imm < 0) imm += 4294967296
|
||||||
setreg(r9_7, int(imm / (2^shamt)))
|
setreg(r9_7, int(imm / (2^shamt)))
|
||||||
} else if (val == 1) { # C.SRAI
|
} else if(val == 1) { # C.SRAI
|
||||||
if (shamt >= 32) trapout(sprintf("Illegal shift amount %d at 0x%X", shamt, pc-2))
|
if(shamt >= 32) trapout(sprintf("Illegal shift amount %d at 0x%X", shamt, pc-2))
|
||||||
setreg(r9_7, floor(getreg(r9_7) / (2^shamt)))
|
setreg(r9_7, floor(getreg(r9_7) / (2^shamt)))
|
||||||
} else if (val == 2) { # C.ANDI
|
} else if(val == 2) { # C.ANDI
|
||||||
imm = r6_2 + b12 * 32
|
imm = r6_2 + b12 * 32
|
||||||
if (imm >= 32) imm -= 64
|
if(imm >= 32) imm -= 64
|
||||||
setreg(r9_7, bw_and(getreg(r9_7), imm))
|
setreg(r9_7, bw_and(getreg(r9_7), imm))
|
||||||
} else if (val == 3) { # C.SUB, C.XOR, C.OR, C.AND
|
} else if(val == 3) { # C.SUB, C.XOR, C.OR, C.AND
|
||||||
imm = int(r6_2 / 8) % 4
|
imm = int(r6_2 / 8) % 4
|
||||||
if (b12 != 0) trapout(sprintf("Illegal register-register instruction at 0x%X", pc-2))
|
if(b12 != 0) trapout(sprintf("Illegal register-register instruction at 0x%X", pc-2))
|
||||||
if (imm == 0) setreg(r9_7, getreg(r9_7) - getreg(r4_2))
|
if(imm == 0) setreg(r9_7, getreg(r9_7) - getreg(r4_2))
|
||||||
else if (imm == 1) setreg(r9_7, bw_xor(getreg(r9_7), getreg(r4_2)))
|
else if(imm == 1) setreg(r9_7, bw_xor(getreg(r9_7), getreg(r4_2)))
|
||||||
else if (imm == 2) setreg(r9_7, bw_or(getreg(r9_7), getreg(r4_2)))
|
else if(imm == 2) setreg(r9_7, bw_or(getreg(r9_7), getreg(r4_2)))
|
||||||
else if (imm == 3) setreg(r9_7, bw_and(getreg(r9_7), getreg(r4_2)))
|
else if(imm == 3) setreg(r9_7, bw_and(getreg(r9_7), getreg(r4_2)))
|
||||||
}
|
}
|
||||||
} else if (f3 == 6 || f3 == 7) { # C.BEQZ / C.BNEZ
|
} else if(f3 == 6 || f3 == 7) { # C.BEQZ / C.BNEZ
|
||||||
imm = b12 * 256 + (int(r6_2 / 8) % 4) * 64 + (r6_2 % 2) * 32 + (int(r11_7 / 8) % 4) * 8 + (int(r6_2 / 2) % 4) * 2
|
imm = b12 * 256 + (int(r6_2 / 8) % 4) * 64 + (r6_2 % 2) * 32 + (int(r11_7 / 8) % 4) * 8 + (int(r6_2 / 2) % 4) * 2
|
||||||
if (imm >= 256) imm -= 512
|
if(imm >= 256) imm -= 512
|
||||||
val = (f3 == 6) ? (getreg(r9_7) == 0) : (getreg(r9_7) != 0)
|
val = (f3 == 6) ? (getreg(r9_7) == 0) : (getreg(r9_7) != 0)
|
||||||
pc = val ? (pc - 2) + imm : pc
|
pc = val ? (pc - 2) + imm : pc
|
||||||
}
|
}
|
||||||
} else if (op == 2) {
|
} else if(op == 2) {
|
||||||
if (f3 == 0) { # C.SLLI
|
if(f3 == 0) { # C.SLLI
|
||||||
if (shamt >= 32) trapout(sprintf("Illegal shift amount %d at 0x%X", shamt, pc-2))
|
if(shamt >= 32) trapout(sprintf("Illegal shift amount %d at 0x%X", shamt, pc-2))
|
||||||
if (r11_7 != 0) {
|
if(r11_7 != 0) {
|
||||||
setreg(r11_7, (getreg(r11_7) * (2^shamt)) % 4294967296)
|
setreg(r11_7, (getreg(r11_7) * (2^shamt)) % 4294967296)
|
||||||
}
|
}
|
||||||
} else if (f3 == 2) { # C.LWSP
|
} else if(f3 == 2) { # C.LWSP
|
||||||
if (r11_7 == 0) trapout(sprintf("Illegal instruction C.LWSP with rd=0 at 0x%X", pc-2))
|
if(r11_7 == 0) trapout(sprintf("Illegal instruction C.LWSP with rd=0 at 0x%X", pc-2))
|
||||||
imm = (r6_2 % 4) * 64 + b12 * 32 + (int(r6_2 / 4) % 8) * 4
|
imm = (r6_2 % 4) * 64 + b12 * 32 + (int(r6_2 / 4) % 8) * 4
|
||||||
base = (getreg(2) + imm) % 4294967296
|
setreg(r11_7, read_mem(getreg(2) + imm, 4, 1))
|
||||||
if (base < 0) base += 4294967296
|
} else if(f3 == 4) { # C.JR, C.MV, C.JALR, C.ADD
|
||||||
val = MEM[base] + MEM[(base+1)%4294967296]*256 + MEM[(base+2)%4294967296]*65536 + MEM[(base+3)%4294967296]*16777216
|
if(b12 == 0) {
|
||||||
setreg(r11_7, val)
|
if(r6_2 == 0) { # C.JR
|
||||||
} else if (f3 == 4) { # C.JR, C.MV, C.JALR, C.ADD
|
if(r11_7 == 0) trapout(sprintf("Illegal instruction C.JR with rs1=0 at 0x%X", pc-2))
|
||||||
if (b12 == 0) {
|
|
||||||
if (r6_2 == 0) { # C.JR
|
|
||||||
if (r11_7 == 0) trapout(sprintf("Illegal instruction C.JR with rs1=0 at 0x%X", pc-2))
|
|
||||||
pc = getreg(r11_7)
|
pc = getreg(r11_7)
|
||||||
} else { # C.MV
|
} else setreg(r11_7, getreg(r6_2)) # C.MV
|
||||||
setreg(r11_7, getreg(r6_2))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (r6_2 == 0) {
|
if(r6_2 == 0) {
|
||||||
if (r11_7 == 0) { # C.EBREAK
|
if(r11_7 == 0) { # C.EBREAK
|
||||||
trapout(sprintf("EBREAK at 0x%X", pc-2))
|
trapout(sprintf("EBREAK at 0x%X", pc-2))
|
||||||
} else { # C.JALR
|
} else { # C.JALR
|
||||||
imm = getreg(r11_7)
|
imm = getreg(r11_7)
|
||||||
setreg(1, pc)
|
setreg(1, pc)
|
||||||
pc = imm
|
pc = imm
|
||||||
}
|
}
|
||||||
} else { # C.ADD
|
} else setreg(r11_7, getreg(r11_7) + getreg(r6_2)) # C.ADD
|
||||||
setreg(r11_7, getreg(r11_7) + getreg(r6_2))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (f3 == 6) { # C.SWSP
|
} else if(f3 == 6) { # C.SWSP
|
||||||
imm = (r11_7 % 4) * 64 + int(r11_7 / 4) * 4 + b12 * 32
|
imm = (r11_7 % 4) * 64 + int(r11_7 / 4) * 4 + b12 * 32
|
||||||
base = (getreg(2) + imm) % 4294967296
|
write_mem(getreg(2) + imm, getreg(r6_2), 4)
|
||||||
if (base < 0) base += 4294967296
|
|
||||||
val = getreg(r6_2)
|
|
||||||
if (val < 0) val += 4294967296
|
|
||||||
MEM[base] = val % 256
|
|
||||||
MEM[(base+1)%4294967296] = int(val/256) % 256
|
|
||||||
MEM[(base+2)%4294967296] = int(val/65536) % 256
|
|
||||||
MEM[(base+3)%4294967296] = int(val/16777216) % 256
|
|
||||||
} else trapout(sprintf("Illegal instruction at 0x%X", pc-2))
|
} else trapout(sprintf("Illegal instruction at 0x%X", pc-2))
|
||||||
} else trapout(sprintf("Illegal instruction at 0x%X", pc-2))
|
} else trapout(sprintf("Illegal instruction at 0x%X", pc-2))
|
||||||
}
|
}
|
||||||
|
|
||||||
# main instruction decoding and execution routine
|
# main instruction decoding and execution routine
|
||||||
function amach_exec(instr, opcode, rd, rs1, rs2, imm, funct3, funct7) {
|
function amach_exec(instr, opcode, rd, rs1, rs2, imm, funct3, funct7) {
|
||||||
if ((instr % 4) != 3) {
|
if((instr % 4) != 3) {
|
||||||
amach_comp(instr)
|
amach_comp(instr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user