Skip to content
This repository was archived by the owner on Jul 17, 2024. It is now read-only.

Commit f3ef892

Browse files
authored
Merge pull request #21 from AkihiroSuda/dev
inst: optimize static jump
2 parents ff3e62d + 1838d74 commit f3ef892

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

pkg/compile/compile.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,13 @@ func generateReadRegExpr(reg decoder.RegisterIndex) string {
258258
return fmt.Sprintf("_ma_regs.x[%d]", reg)
259259
}
260260

261+
func generateStaticJumpStmt(addr, segHead, segSize uint64) string {
262+
if (addr - segHead) < segSize {
263+
return fmt.Sprintf("goto L_0x%08X;", addr)
264+
}
265+
return fmt.Sprintf("return 0x%08X;", addr)
266+
}
267+
261268
func generateCodeFunc(w io.Writer, r io.Reader, segHead, segSize uint64) error {
262269
fmt.Fprintf(w, "_ma_reg_t static _ma_code_func_0x%08X(_ma_reg_t pc_initial){\n", segHead)
263270
fmt.Fprintln(w, "const static void *addr_labels[] = {")
@@ -266,31 +273,33 @@ func generateCodeFunc(w io.Writer, r io.Reader, segHead, segSize uint64) error {
266273
}
267274
fmt.Fprintln(w, "}; /* addr_labels */")
268275
fmt.Fprintf(w, "#define _MA_JUMP(addr) __MA_JUMP((addr), 0x%08X, %d, addr_labels)\n", segHead, segSize)
276+
fmt.Fprintf(w, "#define _MA_JUMP_NEAR(addr) __MA_JUMP_NEAR((addr), 0x%08X, addr_labels)\n", segHead)
269277
fmt.Fprintln(w, "/* Temp variables */")
270278
fmt.Fprintln(w, "uint8_t u8;")
271279
fmt.Fprintln(w, "uint16_t u16;")
272280
fmt.Fprintln(w, "uint32_t u32, u32_x, u32_y;")
273281
fmt.Fprintln(w, "void *p;")
274-
fmt.Fprintln(w, "_MA_JUMP(pc_initial)\n;")
282+
fmt.Fprintln(w, "_MA_JUMP_NEAR(pc_initial);")
275283

276284
for instAddr := segHead; instAddr < segHead+segSize; instAddr += 4 {
277285
var inst32 uint32
278286
if err := binary.Read(r, binary.LittleEndian, &inst32); err != nil {
279287
return err
280288
}
281-
if err := generateCodeEntry(w, segHead, instAddr, inst32); err != nil {
289+
if err := generateCodeEntry(w, segHead, segSize, instAddr, inst32); err != nil {
282290
return fmt.Errorf("%w (addr=0x%08X, instruction=0x%08X)", err, instAddr, inst32)
283291
}
284292
}
285293

286294
fmt.Fprintln(w, "#undef _MA_JUMP")
295+
fmt.Fprintln(w, "#undef _MA_JUMP_NEAR")
287296
fmt.Fprintf(w, "return 0x%08X\n;", segHead+segSize)
288297
fmt.Fprintf(w, "} /* _ma_code_func_0x%08X */\n", segHead)
289298
fmt.Fprintln(w, "")
290299
return nil
291300
}
292301

293-
func generateCodeEntry(w io.Writer, segHead, instAddr uint64, inst32 uint32) error {
302+
func generateCodeEntry(w io.Writer, segHead, segSize, instAddr uint64, inst32 uint32) error {
294303
fmt.Fprintf(w, "L_0x%08X:\n", instAddr)
295304
if logrus.GetLevel() >= logrus.DebugLevel {
296305
fmt.Fprintf(w, "_ma_regs_dump(0x%08X);\n", instAddr)
@@ -414,19 +423,20 @@ func generateCodeEntry(w io.Writer, segHead, instAddr uint64, inst32 uint32) err
414423
}
415424
case decoder.Branch:
416425
rs1, rs2, imm := inst.GetRs1(), inst.GetRs2(), inst.GetImmediate()
426+
stmt := generateStaticJumpStmt(instAddr+uint64(signext.SignExt(int(imm), 13)), segHead, segSize)
417427
switch f3 := inst.GetFunct3(); f3 {
418428
case decoder.Beq: // beq rs1,rs2,offset: if (x[rs1] == x[rs2]) pc += sext(offset)
419-
fmt.Fprintf(w, "if (%s == %s) { _MA_JUMP(0x%08X); }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), instAddr+uint64(signext.SignExt(int(imm), 13)))
429+
fmt.Fprintf(w, "if (%s == %s) { %s }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), stmt)
420430
case decoder.Bne: // bne rs1,rs2,offset: if (x[rs1] != x[rs2]) pc += sext(offset)
421-
fmt.Fprintf(w, "if (%s != %s) { _MA_JUMP(0x%08X); }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), instAddr+uint64(signext.SignExt(int(imm), 13)))
431+
fmt.Fprintf(w, "if (%s != %s) { %s }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), stmt)
422432
case decoder.Blt: // blt rs1,rs2,offset: if (x[rs1] <s x[rs2]) pc += sext(offset) // signed
423-
fmt.Fprintf(w, "if ((signed)%s < (signed)%s) { _MA_JUMP(0x%08X); }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), instAddr+uint64(signext.SignExt(int(imm), 13)))
433+
fmt.Fprintf(w, "if ((signed)%s < (signed)%s) { %s }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), stmt)
424434
case decoder.Bltu: // bltu rs1,rs2,offset: if (x[rs1] <u x[rs2]) pc += sext(offset) // unsigned
425-
fmt.Fprintf(w, "if (%s < %s) { _MA_JUMP(0x%08X); }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), instAddr+uint64(signext.SignExt(int(imm), 13)))
435+
fmt.Fprintf(w, "if (%s < %s) { %s }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), stmt)
426436
case decoder.Bge: // bge rs1,rs2,offset: if (x[rs1] >=s x[rs2]) pc += sext(offset) // signed
427-
fmt.Fprintf(w, "if ((signed)%s >= (signed)%s) { _MA_JUMP(0x%08X); }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), instAddr+uint64(signext.SignExt(int(imm), 13)))
437+
fmt.Fprintf(w, "if ((signed)%s >= (signed)%s) { %s }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), stmt)
428438
case decoder.Bgeu: // bgeu rs1,rs2,offset: if (x[rs1] >=u x[rs2]) pc += sext(offset) // unsigned
429-
fmt.Fprintf(w, "if (%s >= %s) { _MA_JUMP(0x%08X); }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), instAddr+uint64(signext.SignExt(int(imm), 13)))
439+
fmt.Fprintf(w, "if (%s >= %s) { %s }\n", generateReadRegExpr(rs1), generateReadRegExpr(rs2), stmt)
430440
default:
431441
return fmt.Errorf("unsupported Branch funct3 %+v", f3)
432442
}
@@ -447,7 +457,7 @@ func generateCodeEntry(w io.Writer, segHead, instAddr uint64, inst32 uint32) err
447457
if rd != 0 {
448458
fmt.Fprintf(w, "_ma_regs.x[%d] = 0x%08X;\n", rd, instAddr+4)
449459
}
450-
fmt.Fprintf(w, "_MA_JUMP(0x%08X);\n", instAddr+uint64(signext.SignExt(int(imm), 21)))
460+
fmt.Fprintf(w, "%s;\n", generateStaticJumpStmt(instAddr+uint64(signext.SignExt(int(imm), 21)), segHead, segSize))
451461
case decoder.Jalr: // jalr rd,rs1,offset: t =pc+4; pc=(x[rs1]+sext(offset))&∼1; x[rd]=t
452462
rd, rs1, imm := inst.GetRd(), inst.GetRs1(), inst.GetImmediate()
453463
if rd != 0 {

0 commit comments

Comments
 (0)