diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-10-18 19:59:29 +0200 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-10-18 19:59:29 +0200 | 
| commit | 0cb5824977dbff51fa7b77c20279b6bd4cb49d78 (patch) | |
| tree | 80af90f2bfda5a6e2c24e08a01b72a3a6b9bef13 | |
| parent | fe722b9304052b7a0a67fe01633c24ba5b4cdafa (diff) | |
Implemented optimize()
| -rw-r--r-- | asm/chunk.h | 8 | ||||
| -rw-r--r-- | asm/segment.cpp | 31 | ||||
| -rw-r--r-- | test-asm.cpp | 14 | 
3 files changed, 48 insertions, 5 deletions
| diff --git a/asm/chunk.h b/asm/chunk.h index 43cf54e..fb3f303 100644 --- a/asm/chunk.h +++ b/asm/chunk.h @@ -25,12 +25,12 @@ struct AddressFeature   bool relativeAddressing{true};   std::vector<uint8_t> machine_code; - size_t addr_size; - size_t addr_offs; ///< offset inside code + size_t addr_size{0}; + size_t addr_offs{0}; ///< offset inside code   std::vector<uint8_t> alternative_code; - size_t alternative_size; - size_t alternative_offs; ///< offset inside code + size_t alternative_size{0}; + size_t alternative_offs{0}; ///< offset inside code  };  class Label: public Chunk diff --git a/asm/segment.cpp b/asm/segment.cpp index a4544f2..d3050bb 100644 --- a/asm/segment.cpp +++ b/asm/segment.cpp @@ -79,6 +79,35 @@ void Segment::insertAddresses()  void Segment::optimize()  { - // TODO + bool changed{false}; + + for (size_t i = 0; i < this->size(); i++) { +  try { +   AddressFeature& af { dynamic_cast<AddressFeature&>(*((*this)[i]))}; + +   if (af.relativeAddressing == false) +    throw std::runtime_error("Error: Absolute Addressing not supported."); + +   if (!af.alternative_code.empty()) { +    int64_t target_address = getAddressOfLabel(af.label); // throws if label not found +    int64_t start_address = getAddressOfIndex(i); // throws if out of range +    int64_t diff = target_address - start_address; +    if (af.addr_size == 4 && af.alternative_size == 1 && diff >= -128 && diff <= 127) { +     af.machine_code = af.alternative_code; +     af.addr_size = af.alternative_size; +     af.addr_offs = af.alternative_offs; +     af.alternative_code.clear(); +     af.alternative_size = 0; +     af.alternative_offs = 0; +     changed = true; +    } +   } +  } catch (const std::bad_cast& ex) { +   // ignore, expected for non-addressing chunks +  } + } + + if (changed) +  insertAddresses(); // renumber  } diff --git a/test-asm.cpp b/test-asm.cpp index efdeab9..1d4634e 100644 --- a/test-asm.cpp +++ b/test-asm.cpp @@ -115,4 +115,18 @@ TEST_F(AsmTest, Intel64_multiple) {     0xE9, 0xFF, 0xFF, 0xFF, 0xFF, // jmp data1     0x01, 0x02, 0x03 // data    })); +  + segment.optimize(); +  + ASSERT_EQ(segment.size(), 7); + ASSERT_EQ(segment.getCode(), std::vector<uint8_t>( +  { +   0x90, // nop +   0xCD, 0x05, // int 5 +   0xC3, // ret +   // data1: +   0xC3, // ret +   0xEB, 0xFF, // jmp data1 +   0x01, 0x02, 0x03 // data +  }));  } | 
