summaryrefslogtreecommitdiff
path: root/startop/view_compiler/dex_builder.h
diff options
context:
space:
mode:
authorEric Holk <eholk@google.com>2018-11-09 13:48:59 -0800
committerEric Holk <eholk@google.com>2018-11-15 17:44:03 +0000
commit1c0f3f099cf6420af16a9ab29f3bdf6721ac78a3 (patch)
treefdbb0b490b40357607fc5673633c221669286a12 /startop/view_compiler/dex_builder.h
parent2583def750214a34b674d128bc1763f742015dba (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.h46
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;