Commit Graph

33 Commits

Author SHA1 Message Date
Alessandro Di Federico d57b222ca2 Fix return type while translating bswap 2016-08-20 03:10:45 +02:00
Alessandro Di Federico 710954ee51 Use a single, shared, cast for local temporaries 2016-08-20 03:10:45 +02:00
Alessandro Di Federico da2b42901b Reset temporaries for each new input instruction 2016-08-20 03:10:45 +02:00
Alessandro Di Federico ff52a06c74 Unify return values for opcode translations
Now `CodeGenerator::translate`, `CodeGenerator::translateCall` and
`CodeGenerator::newInstruction` all return
`CodeGenerator::TranslationResult` which covers all the possible results
that the caller needs to handle such abort, stop translation, force a
new basic block or simply proceed.

This patch also prevents reading a PTC temporary that has never been
written (typically due to a mistranslation) by emitting an abort.
2016-08-20 03:10:45 +02:00
Alessandro Di Federico 329fcb3707 Introduce tracing support 2016-08-20 03:10:45 +02:00
Alessandro Di Federico 6acc701b54 Documentation and some refactoring 2016-08-20 03:10:45 +02:00
Alessandro Di Federico fbca5bba2e Import OSRA and update SET
* Import OSRA
* Improve the SET (aka `JumpTargetFromConstants`) by introducing the
  `OperationsStack` class.
* Review `harvest` logic
* Allow to disable OSRA (along with the sumjump heuristic)
* Take the core of `getNextPC` out of it and move it to `getPC`, a
  function returning both the current and the next PC. Also, fix a bug
  when reaching the beginning of a basic block.
* Detect "reliable" jump targets: a "reliable" jump target is a jump
  target obtained from a store to a PC but it's not a fallthrough jump.
2016-08-20 03:10:39 +02:00
Alessandro Di Federico cda7bbd94e Extend support for partial CPU state reads/writes
This patch implements `VariableManager::storeToCPUStateOffset` and
`VariableManager::loadFromCPUStateOffset`, which handle in a single
point all the accesses by offset to the CPU state.

* `getTypeAtOffset`: introduce a feature to easily debug how we compute
  which field is at a specified offset in the CPU state (`--debug
  type-at-offset`).
* Let `getTypeAtOffset` and its wrappers return the offset inside a
  field of the CPU state (useful when accessing the third byte of an
  integer).
* Use a dedicated class for the `CorrectCPUStateUsage` worklist
2016-04-14 16:10:13 +02:00
Alessandro Di Federico 2a2306c0ae Improve new basic block positioning 2016-04-14 16:10:13 +02:00
Alessandro Di Federico 3daa285640 Fix bug in translation of rotate 2016-04-14 16:10:13 +02:00
Alessandro Di Federico 0f255102cd Handle helpers that might change the PC
If before a call to an heper the PC is saved, it means that the helper
can change the PC, therefore we need to go the dispatcher on return. In
this case, we also have to force the PC after the call to be a jump
target.
2016-04-14 16:10:13 +02:00
Alessandro Di Federico 6814f0c595 Compute explicitly the next PC while translating
When we meet a new PC from the PTC input, find immediately the next PC.
This makes the information available early and removes the necessity for
`closeLastInstruction`.
2016-04-14 16:10:13 +02:00
Alessandro Di Federico c94fad95e4 Produce coverage CSV
Implement producing a CSV file containing information about the which
PCs have been translated. For each PC it is specified whether its a jump
target or not.
2016-04-14 16:10:13 +02:00
Alessandro Di Federico 7a1ed8826b Coverage: explore PC after syscall 2016-04-14 16:10:13 +02:00
Alessandro Di Federico 3f2ce746ec Bug: do not sign extend composed values in add2 2016-02-02 16:51:07 +01:00
Alessandro Di Federico 8df95158fb Bug: missing breaks in bswap PTC operation 2016-02-02 16:50:39 +01:00
Alessandro Di Federico 318b478a92 Attach local temporaries to newpc calls
Pass local temporaries' allocas as parameters to newpc, so they can't be
promoted to SSA values by SROA, which creates problem when a basic block
must be split between a use and a def of such a value.
2016-02-02 16:48:32 +01:00
Alessandro Di Federico e59edd4109 Improve code pointer harvesting using GVN
If EarlyCSE didn't produce any new code pointer, we use
GlobalValueNumbering which usually leads to better results, in
particular if we remove `newpc` markers and if it can make use of alias
information, which we introduce to let the compiler know that
loads/stores to the CPU state will never alias loads/stores to normal
memory.

* Before generating any load/store instruction mark it with the
  appropriate aliasing information.
* Update `JumpTargetManager::harvest` to run GVN
* Move the `Visited` set of `JumpTargetsFromConstantsPass` in
  `JumpTargetManager`, even if currently we clear it at each invocation
  of the pass
2016-01-30 11:14:20 +01:00
Alessandro Di Federico 3746bcbd78 Move harvesting of code pointers in JTM
The logic to implement harvesting of new code pointers when we're out of
them during translation, has been moved to `JumpTargetManager`. Its
interface has also been reduced and some logging has been introduced.

At the current stage, if there's nothing to `peek`, we first give a shot
of `SROA` and `TranslateDirectBranchesPass`, and then, if nothing came
out, we go for `EarlyCSE` and `JumpTargetsFromConstantsPass`.
2016-01-12 23:28:23 +01:00
Alessandro Di Federico 8c381090a7 Move TranslateDirectBranchesPass to JTM 2016-01-12 23:05:29 +01:00
Alessandro Di Federico ef98afc1e3 Insert an unreachable after exit_tb
Introduce an unreachable instruction after each emitted call to
`exit_tb` to terminate properly basic blocks. This patch also removes it
when appropropriate (i.e. in `TranslateDirectBranchesPass` and
`JumpTargetManager::translateIndirectJumps`).
2016-01-12 19:41:37 +01:00
Alessandro Di Federico 0280d0fc98 Divert translation to a new block after exit_tb 2016-01-12 18:47:10 +01:00
Alessandro Di Federico e2e6a9cdb8 Introduce early detection of jump targets
Detect simplest cases of writes to the program counter while they're
being translated. This way, we avoid running expensive passes to collect
straightforward jump targets.

Note: if the PC-write value is the current PC, ignore it. Splitting the
basic block being created is problematic.
2016-01-12 18:38:24 +01:00
Alessandro Di Federico 21d7cce3bf Graceful handling of translation failure
* Let `InstructionTranslator::newInstruction` return also the PC.
* `InstructionTranslator::translate`: make it aware of the current PC,
  and make it abort in case of error and return a boolean to indicate
  whether the translation should proceed or not.
* Simplify the fetch of a new address to translate.
* Let `InstructionTranslator::translateOpcode` return an error condition
  in case of failure, instead of asserting.
2016-01-12 18:38:18 +01:00
Alessandro Di Federico 7fec929195 Fix typo in handling of op_{div,mul}u2_i{32,64} 2016-01-12 18:17:05 +01:00
Alessandro Di Federico 432e89895b Harvest possible code pointers from code constants
* Introduce the `JumpTargetsFromConstantsPass` pass, which goes through
  all the unvisited basic blocks looking for constants and trying to feed
  them to `JumpTargetManager`, which will decide if they are code
  pointers or not.
* To make life of `JumpTargetsFromConstantsPass` easier run
  `EarlyCSEPass` before it, which is particularly useful to make explicit
  constants that some architectures materialize in two steps (high and
  low part).
* Remove the fake fallthrough workaround in `TranslateDirectBranchesPass`
  which was used to register for exploration basic blocks after a direct
  jump, which was necessary due to the fact that return instructions are
  indirect jumps and were losing the basic blocks after function calls.
  This is no longer necessary thanks to `JumpTargetsFromConstantsPass`.
2016-01-09 11:25:17 +01:00
Alessandro Di Federico 39b9e69773 Bug: use a reverse iterator in getNextPC
In `TranslateDirectBranchesPass::getNextPC` we were using a normal
iterator backward with a faulty exit condition that lead us to skip the
first instruction in a basic block.
This patch implements a proper solution: use `reverse_iterator`.
2016-01-09 11:05:44 +01:00
Alessandro Di Federico 93eb350073 Add support for source-target endianess mismatch 2016-01-07 14:17:15 +01:00
Alessandro Di Federico 8e3268c9c0 Handle post-helper indirect jumps
In certain cases we have a call to `exitTB` right after an helper, in
particular in x86, after a syscall. We cannot know what the target
address will be, so we have to handle this as an indirect jump.

* `JumpTargetManager::getPrevPCWrite`: clean up.
* `JumpTargetManager::getPrevPCWrite`: while searching for stores to the
  PC, also check for call instructions. If one is met, return nullptr.
* `TranslateDirectBranchesPass::runOnFunction` and
  `JumpTargetManager::translateIndirectJumps`: insert new code before
  `exitTB`, not the write to the PC.
2016-01-04 21:29:03 +01:00
Alessandro Di Federico 6338f3b0b8 Link with helpers and adjust their CPU state usage
* Move initialization and management of the structure describing the CPU
  state (CPUStateType) into variablemanager.cpp.
* Support parts of CPU state outside "env" (e.g. the MIPSCPU
  structure). Now "env" has an offset into the possibly larger CPU state
  which we have to take into account where appropriate (see
  VariableManager::envOffset).
* Link the helpers module into the generated module, including only what
  is needed.
* Create some "no-op" or "abort" function corresponding to QEMU functions
  not included in the helper module (e.g. logging and abort functions).
* Implement the CorrectCPUStateUsagePass pass, which starts from the
  "env" global variable and looks for all its usages recursively, keeping
  track of where pointers are pointing into the CPU state data structure,
  and replaces all the load/stores with the global variable corresponding
  to that specific field of the CPU state.
* After the linking phase, run SROA, the pass to adjust the CPU usage and
  DCE.
* Let global variables have common linkage.
2015-12-04 23:44:46 +01:00
Alessandro Di Federico 9fd83ea336 Implement the exit_tb PTC instruction
* Emit a call to an helper function (ExitTB) corresponding to each
  exit_tb PTC instruction.
* Update TranslateDirectBranchesPass and
  JumpTargetManager::translateIndirectJumps to look for the last write
  to the PC before calls to ExitTB.
* Exposing the PC with JumpTargetManager::PC is not needed anymore. Users
  from outside should only be interested in finding the the previous
  write to the PC (using JumpTargetManager::getPrevPCWrite).
2015-12-03 18:02:52 +01:00
Alessandro Di Federico 4e326f5799 Factorize LLVM-related helper functions 2015-12-03 17:59:32 +01:00
Alessandro Di Federico 5d130b7072 Split ptctollvmir.cpp into multiple files 2015-11-24 15:21:17 +01:00