|
32 | 32 |
|
33 | 33 | OPCODE_ST = 6
|
34 | 34 | SUB_OPCODE_ST_AUTO = 1
|
35 |
| -SUB_OPCODE_ST_OFFSET = 3 |
| 35 | +# Note: SUB_OPCODE_ST_OFFSET should be 3 |
| 36 | +# But in binutils-gdb they hardcoded the value to 2 |
| 37 | +# This appears to be a bug, if one looks at the Technical |
| 38 | +# Reference Manual of the ESP32-S2. |
| 39 | +# |
| 40 | +# This issue is reported as a pull-request with fix: |
| 41 | +# https://github.com/espressif/binutils-gdb/pull/2 |
| 42 | +# |
| 43 | +# We'll hard code this to 2 for now, until this is resolved in |
| 44 | +# binutils-gdb or the Technical Reference Manual is updated. |
| 45 | +SUB_OPCODE_ST_OFFSET = 2 # should be 3 |
36 | 46 | SUB_OPCODE_ST = 4
|
37 | 47 |
|
38 | 48 | OPCODE_ALU = 7
|
@@ -467,37 +477,101 @@ def i_adc(reg_dest, adc_idx, mux, _not_used=None):
|
467 | 477 | return _adc.all
|
468 | 478 |
|
469 | 479 |
|
470 |
| -def i_st(reg_val, reg_addr, offset): ## FIXME do via i_st_manual |
| 480 | +def i_st_manual(reg_val, reg_addr, offset, label, upper, wr_way): |
471 | 481 | _st.dreg = get_reg(reg_addr)
|
472 | 482 | _st.sreg = get_reg(reg_val)
|
| 483 | + _st.label = get_imm(label) |
| 484 | + _st.upper = upper |
| 485 | + _st.wr_way = wr_way |
| 486 | + _st.unused1 = 0 |
| 487 | + _st.offset = get_imm(offset) // 4 |
| 488 | + _st.unused2 = 0 |
| 489 | + _st.sub_opcode = SUB_OPCODE_ST |
| 490 | + _st.opcode = OPCODE_ST |
| 491 | + return _st.all |
| 492 | + |
| 493 | + |
| 494 | +def i_stl(reg_val, reg_addr, offset, label="0"): |
| 495 | + return i_st_manual(reg_val, reg_addr, offset, label, 0, 3 if label=="0" else 1) |
| 496 | + |
| 497 | + |
| 498 | +def i_sth(reg_val, reg_addr, offset, label="0"): |
| 499 | + return i_st_manual(reg_val, reg_addr, offset, label, 1, 3 if label=="0" else 1) |
| 500 | + |
| 501 | + |
| 502 | +def i_st(reg_val, reg_addr, offset): |
| 503 | + return i_stl(reg_val, reg_addr, offset) |
| 504 | + |
| 505 | + |
| 506 | +def i_st32(reg_val, reg_addr, offset, label): |
| 507 | + return i_st_manual(reg_val, reg_addr, offset, label, 0, 0) |
| 508 | + |
| 509 | + |
| 510 | +def i_st_auto(reg_val, reg_addr, label, wr_way): |
| 511 | + _st.dreg = get_reg(reg_addr) |
| 512 | + _st.sreg = get_reg(reg_val) |
| 513 | + _st.label = get_imm(label) |
| 514 | + _st.upper = 0 |
| 515 | + _st.wr_way = wr_way |
| 516 | + _st.unused1 = 0 |
| 517 | + _st.offset = 0 |
| 518 | + _st.unused2 = 0 |
| 519 | + _st.sub_opcode = SUB_OPCODE_ST_AUTO |
| 520 | + _st.opcode = OPCODE_ST |
| 521 | + return _st.all |
| 522 | + |
| 523 | + |
| 524 | +def i_sto(offset): |
| 525 | + _st.dreg = 0 |
| 526 | + _st.sreg = 0 |
473 | 527 | _st.label = 0
|
474 | 528 | _st.upper = 0
|
475 |
| - _st.wr_way = 3 |
| 529 | + _st.wr_way = 0 |
476 | 530 | _st.unused1 = 0
|
477 | 531 | _st.offset = get_imm(offset) // 4
|
478 | 532 | _st.unused2 = 0
|
479 |
| - _st.sub_opcode = SUB_OPCODE_ST |
| 533 | + _st.sub_opcode = SUB_OPCODE_ST_OFFSET |
480 | 534 | _st.opcode = OPCODE_ST
|
481 | 535 | return _st.all
|
482 | 536 |
|
483 | 537 |
|
| 538 | +def i_sti(reg_val, reg_addr, label="0"): |
| 539 | + return i_st_auto(reg_val, reg_addr, label, 3 if label=="0" else 1) |
| 540 | + |
| 541 | + |
| 542 | +def i_sti32(reg_val, reg_addr, label): |
| 543 | + return i_st_auto(reg_val, reg_addr, label, 0) |
| 544 | + |
| 545 | + |
484 | 546 | def i_halt():
|
485 | 547 | _halt.unused = 0
|
486 | 548 | _halt.opcode = OPCODE_HALT
|
487 | 549 | return _halt.all
|
488 | 550 |
|
489 | 551 |
|
490 |
| -def i_ld(reg_dest, reg_addr, offset): ## FIXME do via i_ld_manual |
| 552 | +def i_ld_manual(reg_dest, reg_addr, offset, rd_upper): |
491 | 553 | _ld.dreg = get_reg(reg_dest)
|
492 | 554 | _ld.sreg = get_reg(reg_addr)
|
493 | 555 | _ld.unused1 = 0
|
494 | 556 | _ld.offset = get_imm(offset) // 4
|
495 | 557 | _ld.unused2 = 0
|
496 |
| - _ld.rd_upper = 0 |
| 558 | + _ld.rd_upper = rd_upper |
497 | 559 | _ld.opcode = OPCODE_LD
|
498 | 560 | return _ld.all
|
499 | 561 |
|
500 | 562 |
|
| 563 | +def i_ldl(reg_dest, reg_addr, offset): |
| 564 | + return i_ld_manual(reg_dest, reg_addr, offset, 0) |
| 565 | + |
| 566 | + |
| 567 | +def i_ldh(reg_dest, reg_addr, offset): |
| 568 | + return i_ld_manual(reg_dest, reg_addr, offset, 1) |
| 569 | + |
| 570 | + |
| 571 | +def i_ld(reg_dest, reg_add
F438
r, offset): |
| 572 | + return i_ldl(reg_dest, reg_addr, offset) |
| 573 | + |
| 574 | + |
501 | 575 | def i_move(reg_dest, reg_imm_src):
|
502 | 576 | # this is the only ALU instruction with 2 args: move r0, r1
|
503 | 577 | dest = get_reg(reg_dest)
|
|
0 commit comments