@@ -258,6 +258,13 @@ func generateReadRegExpr(reg decoder.RegisterIndex) string {
258
258
return fmt .Sprintf ("_ma_regs.x[%d]" , reg )
259
259
}
260
260
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
+
261
268
func generateCodeFunc (w io.Writer , r io.Reader , segHead , segSize uint64 ) error {
262
269
fmt .Fprintf (w , "_ma_reg_t static _ma_code_func_0x%08X(_ma_reg_t pc_initial){\n " , segHead )
263
270
fmt .Fprintln (w , "const static void *addr_labels[] = {" )
@@ -266,31 +273,33 @@ func generateCodeFunc(w io.Writer, r io.Reader, segHead, segSize uint64) error {
266
273
}
267
274
fmt .Fprintln (w , "}; /* addr_labels */" )
268
275
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 )
269
277
fmt .Fprintln (w , "/* Temp variables */" )
270
278
fmt .Fprintln (w , "uint8_t u8;" )
271
279
fmt .Fprintln (w , "uint16_t u16;" )
272
280
fmt .Fprintln (w , "uint32_t u32, u32_x, u32_y;" )
273
281
fmt .Fprintln (w , "void *p;" )
274
- fmt .Fprintln (w , "_MA_JUMP (pc_initial)\n ;" )
282
+ fmt .Fprintln (w , "_MA_JUMP_NEAR (pc_initial);" )
275
283
276
284
for instAddr := segHead ; instAddr < segHead + segSize ; instAddr += 4 {
277
285
var inst32 uint32
278
286
if err := binary .Read (r , binary .LittleEndian , & inst32 ); err != nil {
279
287
return err
280
288
}
281
- if err := generateCodeEntry (w , segHead , instAddr , inst32 ); err != nil {
289
+ if err := generateCodeEntry (w , segHead , segSize , instAddr , inst32 ); err != nil {
282
290
return fmt .Errorf ("%w (addr=0x%08X, instruction=0x%08X)" , err , instAddr , inst32 )
283
291
}
284
292
}
285
293
286
294
fmt .Fprintln (w , "#undef _MA_JUMP" )
295
+ fmt .Fprintln (w , "#undef _MA_JUMP_NEAR" )
287
296
fmt .Fprintf (w , "return 0x%08X\n ;" , segHead + segSize )
288
297
fmt .Fprintf (w , "} /* _ma_code_func_0x%08X */\n " , segHead )
289
298
fmt .Fprintln (w , "" )
290
299
return nil
291
300
}
292
301
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 {
294
303
fmt .Fprintf (w , "L_0x%08X:\n " , instAddr )
295
304
if logrus .GetLevel () >= logrus .DebugLevel {
296
305
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
414
423
}
415
424
case decoder .Branch :
416
425
rs1 , rs2 , imm := inst .GetRs1 (), inst .GetRs2 (), inst .GetImmediate ()
426
+ stmt := generateStaticJumpStmt (instAddr + uint64 (signext .SignExt (int (imm ), 13 )), segHead , segSize )
417
427
switch f3 := inst .GetFunct3 (); f3 {
418
428
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 )
420
430
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 )
422
432
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 )
424
434
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 )
426
436
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 )
428
438
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 )
430
440
default :
431
441
return fmt .Errorf ("unsupported Branch funct3 %+v" , f3 )
432
442
}
@@ -447,7 +457,7 @@ func generateCodeEntry(w io.Writer, segHead, instAddr uint64, inst32 uint32) err
447
457
if rd != 0 {
448
458
fmt .Fprintf (w , "_ma_regs.x[%d] = 0x%08X;\n " , rd , instAddr + 4 )
449
459
}
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 ))
451
461
case decoder .Jalr : // jalr rd,rs1,offset: t =pc+4; pc=(x[rs1]+sext(offset))&∼1; x[rd]=t
452
462
rd , rs1 , imm := inst .GetRd (), inst .GetRs1 (), inst .GetImmediate ()
453
463
if rd != 0 {
0 commit comments