diff options
| -rw-r--r-- | backend/regfile.h | 1 | ||||
| -rw-r--r-- | frontend/decode.h | 15 | ||||
| -rw-r--r-- | inst.h | 1 | ||||
| -rw-r--r-- | tests/loop-indirect.hex | 1 |
4 files changed, 15 insertions, 3 deletions
diff --git a/backend/regfile.h b/backend/regfile.h index 276504c..4cf328a 100644 --- a/backend/regfile.h +++ b/backend/regfile.h | |||
| @@ -33,6 +33,7 @@ namespace backend { | |||
| 33 | auto i = writebackp.read(); | 33 | auto i = writebackp.read(); |
| 34 | if (i.generation == generation_down) { | 34 | if (i.generation == generation_down) { |
| 35 | pte(i.transaction, "W", fmt::format("writeback gen={} pc={:x}", generation_down, pc)); | 35 | pte(i.transaction, "W", fmt::format("writeback gen={} pc={:x}", generation_down, pc)); |
| 36 | assert(pc == i.init_pc); | ||
| 36 | auto old_pc = pc; | 37 | auto old_pc = pc; |
| 37 | pc = i.linear_next_pc; | 38 | pc = i.linear_next_pc; |
| 38 | switch (i.field[OPCODE]) { | 39 | switch (i.field[OPCODE]) { |
diff --git a/frontend/decode.h b/frontend/decode.h index 717d0f6..cb7bedd 100644 --- a/frontend/decode.h +++ b/frontend/decode.h | |||
| @@ -24,15 +24,20 @@ namespace frontend { | |||
| 24 | unsigned int generation_down = 0; | 24 | unsigned int generation_down = 0; |
| 25 | std::uint64_t pc = 0; | 25 | std::uint64_t pc = 0; |
| 26 | 26 | ||
| 27 | std::uint64_t indirect_jump_origin = ~(std::uint64_t)0; | ||
| 28 | std::uint64_t indirect_jump_destination = ~(std::uint64_t)0; | ||
| 29 | |||
| 27 | static constexpr unsigned int MAX_INST_SIZE = 64; | 30 | static constexpr unsigned int MAX_INST_SIZE = 64; |
| 28 | static constexpr unsigned int BYTES_PER_CYCLE = 4; | 31 | static constexpr unsigned int BYTES_PER_CYCLE = 1; |
| 29 | 32 | ||
| 30 | void clock() { | 33 | void clock() { |
| 31 | if (restartp.can_read()) { | 34 | if (restartp.can_read()) { |
| 32 | auto r = restartp.read(); | 35 | auto r = restartp.read(); |
| 33 | generation_down = r.new_generation; | 36 | generation_down = r.new_generation; |
| 34 | pc = r.new_pc; | 37 | next_inst.init_pc = pc = r.new_pc; |
| 35 | next_inst.size = 0; | 38 | next_inst.size = 0; |
| 39 | indirect_jump_origin = r.from_pc; | ||
| 40 | indirect_jump_destination = r.new_pc; | ||
| 36 | for (auto &f : next_inst.field) | 41 | for (auto &f : next_inst.field) |
| 37 | f = 0; | 42 | f = 0; |
| 38 | fetch::restart fr; | 43 | fetch::restart fr; |
| @@ -95,7 +100,10 @@ namespace frontend { | |||
| 95 | redirect = target; | 100 | redirect = target; |
| 96 | } | 101 | } |
| 97 | } else if (!taken.has_value() || taken.value()) { | 102 | } else if (!taken.has_value() || taken.value()) { |
| 98 | unpredictable = true; | 103 | if (next_inst.init_pc == indirect_jump_origin) |
| 104 | redirect = indirect_jump_destination; | ||
| 105 | else | ||
| 106 | unpredictable = true; | ||
| 99 | } | 107 | } |
| 100 | } | 108 | } |
| 101 | if (redirect.has_value()) { | 109 | if (redirect.has_value()) { |
| @@ -106,6 +114,7 @@ namespace frontend { | |||
| 106 | next_inst.predicted_next_pc.reset(); | 114 | next_inst.predicted_next_pc.reset(); |
| 107 | } | 115 | } |
| 108 | instp->write(std::move(next_inst)); | 116 | instp->write(std::move(next_inst)); |
| 117 | next_inst.init_pc = pc; | ||
| 109 | next_inst.size = unpredictable ? MAX_INST_SIZE : 0; | 118 | next_inst.size = unpredictable ? MAX_INST_SIZE : 0; |
| 110 | for (auto &f : next_inst.field) | 119 | for (auto &f : next_inst.field) |
| 111 | f = 0; | 120 | f = 0; |
| @@ -8,6 +8,7 @@ struct inst { | |||
| 8 | infra::transaction transaction; | 8 | infra::transaction transaction; |
| 9 | unsigned int generation; | 9 | unsigned int generation; |
| 10 | unsigned int size = 0; | 10 | unsigned int size = 0; |
| 11 | std::uint64_t init_pc = 0; | ||
| 11 | std::uint64_t linear_next_pc; | 12 | std::uint64_t linear_next_pc; |
| 12 | std::optional<std::uint64_t> predicted_next_pc; | 13 | std::optional<std::uint64_t> predicted_next_pc; |
| 13 | std::uint64_t field[4] = {}; | 14 | std::uint64_t field[4] = {}; |
diff --git a/tests/loop-indirect.hex b/tests/loop-indirect.hex new file mode 100644 index 0000000..c8b07f7 --- /dev/null +++ b/tests/loop-indirect.hex | |||
| @@ -0,0 +1 @@ | |||
| 00 # 0: jmp r0 if r0 == 0 | |||
