diff options
author | Eric Holk <eholk@google.com> | 2018-11-09 13:48:59 -0800 |
---|---|---|
committer | Eric Holk <eholk@google.com> | 2018-11-15 17:44:03 +0000 |
commit | 1c0f3f099cf6420af16a9ab29f3bdf6721ac78a3 (patch) | |
tree | fdbb0b490b40357607fc5673633c221669286a12 /startop/view_compiler/dex_builder.h | |
parent | 2583def750214a34b674d128bc1763f742015dba (diff) |
[view_compiler] cleanup: Use format-specific bytecode encoding functions
This change corrals most of the bit shifting and ORing needed to encode Dex
instructions into EncodeXXX functions that follow the naming scheme at
https://source.android.com/devices/tech/dalvik/instruction-formats. Overall, it
makes the code easier to follow and probably even less error prone because we
only have to make the format right in one place.
Bug: 111895153
Change-Id: I902ec3c8bca6b5dc4ad900503af7aef58d4bbf5f
Diffstat (limited to 'startop/view_compiler/dex_builder.h')
-rw-r--r-- | startop/view_compiler/dex_builder.h | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/startop/view_compiler/dex_builder.h b/startop/view_compiler/dex_builder.h index 181d1db0082a..adf82bf9a01a 100644 --- a/startop/view_compiler/dex_builder.h +++ b/startop/view_compiler/dex_builder.h @@ -258,6 +258,52 @@ class MethodBuilder { void EncodeBranch(art::Instruction::Code op, const Instruction& instruction); void EncodeNew(const Instruction& instruction); + // Low-level instruction format encoding. See + // https://source.android.com/devices/tech/dalvik/instruction-formats for documentation of + // formats. + + inline void Encode10x(art::Instruction::Code opcode) { + // 00|op + buffer_.push_back(opcode); + } + + inline void Encode11x(art::Instruction::Code opcode, uint8_t a) { + // aa|op + buffer_.push_back((a << 8) | opcode); + } + + inline void Encode11n(art::Instruction::Code opcode, uint8_t a, int8_t b) { + // b|a|op + + // Make sure the fields are in bounds (4 bits for a, 4 bits for b). + CHECK_LT(a, 16); + CHECK_LE(-8, b); + CHECK_LT(b, 8); + + buffer_.push_back(((b & 0xf) << 12) | (a << 8) | opcode); + } + + inline void Encode21c(art::Instruction::Code opcode, uint8_t a, uint16_t b) { + // aa|op|bbbb + buffer_.push_back((a << 8) | opcode); + buffer_.push_back(b); + } + + inline void Encode35c(art::Instruction::Code opcode, size_t a, uint16_t b, uint8_t c, uint8_t d, + uint8_t e, uint8_t f, uint8_t g) { + // a|g|op|bbbb|f|e|d|c + + CHECK_LE(a, 5); + CHECK_LT(c, 16); + CHECK_LT(d, 16); + CHECK_LT(e, 16); + CHECK_LT(f, 16); + CHECK_LT(g, 16); + buffer_.push_back((a << 12) | (g << 8) | opcode); + buffer_.push_back(b); + buffer_.push_back((f << 12) | (e << 8) | (d << 4) | c); + } + // Converts a register or parameter to its DEX register number. size_t RegisterValue(const Value& value) const; |