summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/builder.cc
diff options
context:
space:
mode:
authorDave Allison <dallison@google.com>2014-06-16 20:44:29 -0700
committerDave Allison <dallison@google.com>2014-06-24 09:05:27 -0700
commit20dfc797dc631bf8d655dcf123f46f13332d3074 (patch)
treec1d4e4f919d54f39a6d39d9d769ed5a844afb22b /compiler/optimizing/builder.cc
parentcbb0e809c0a4e8a4e8b7f5d3768a1864cfb381bb (diff)
downloadart-20dfc797dc631bf8d655dcf123f46f13332d3074.tar.gz
art-20dfc797dc631bf8d655dcf123f46f13332d3074.tar.bz2
art-20dfc797dc631bf8d655dcf123f46f13332d3074.zip
Add some more instruction support to optimizing compiler.
This adds a few more DEX instructions to the optimizing compiler's builder (constants, moves, if_xx, etc). Also: * Changes the codegen for IF_XX instructions to use a condition rather than comparing a value against 0. * Fixes some instructions in the ARM disassembler. * Fixes PushList and PopList in the thumb2 assembler. * Switches the assembler for the optimizing compiler to thumb2 rather than ARM. Change-Id: Iaafcd02243ccc5b03a054ef7a15285b84c06740f
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r--compiler/optimizing/builder.cc104
1 files changed, 86 insertions, 18 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 521992ad3a..c3a322caee 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -93,15 +93,30 @@ static bool CanHandleCodeItem(const DexFile::CodeItem& code_item) {
}
template<typename T>
-void HGraphBuilder::If_22t(const Instruction& instruction, int32_t dex_offset, bool is_not) {
+void HGraphBuilder::If_22t(const Instruction& instruction, int32_t dex_offset) {
HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
- current_block_->AddInstruction(new (arena_) T(first, second));
- if (is_not) {
- current_block_->AddInstruction(new (arena_) HNot(current_block_->GetLastInstruction()));
- }
- current_block_->AddInstruction(new (arena_) HIf(current_block_->GetLastInstruction()));
- HBasicBlock* target = FindBlockStartingAt(instruction.GetTargetOffset() + dex_offset);
+ T* comparison = new (arena_) T(first, second);
+ current_block_->AddInstruction(comparison);
+ HInstruction* ifinst = new (arena_) HIf(comparison);
+ current_block_->AddInstruction(ifinst);
+ HBasicBlock* target = FindBlockStartingAt(dex_offset + instruction.GetTargetOffset());
+ DCHECK(target != nullptr);
+ current_block_->AddSuccessor(target);
+ target = FindBlockStartingAt(dex_offset + instruction.SizeInCodeUnits());
+ DCHECK(target != nullptr);
+ current_block_->AddSuccessor(target);
+ current_block_ = nullptr;
+}
+
+template<typename T>
+void HGraphBuilder::If_21t(const Instruction& instruction, int32_t dex_offset) {
+ HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
+ T* comparison = new (arena_) T(value, GetIntConstant(0));
+ current_block_->AddInstruction(comparison);
+ HInstruction* ifinst = new (arena_) HIf(comparison);
+ current_block_->AddInstruction(ifinst);
+ HBasicBlock* target = FindBlockStartingAt(dex_offset + instruction.GetTargetOffset());
DCHECK(target != nullptr);
current_block_->AddSuccessor(target);
target = FindBlockStartingAt(dex_offset + instruction.SizeInCodeUnits());
@@ -340,16 +355,38 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
break;
}
+ case Instruction::CONST: {
+ int32_t register_index = instruction.VRegA();
+ HIntConstant* constant = GetIntConstant(instruction.VRegB_31i());
+ UpdateLocal(register_index, constant);
+ break;
+ }
+
+ case Instruction::CONST_HIGH16: {
+ int32_t register_index = instruction.VRegA();
+ HIntConstant* constant = GetIntConstant(instruction.VRegB_21h() << 16);
+ UpdateLocal(register_index, constant);
+ break;
+ }
+
case Instruction::CONST_WIDE_16: {
int32_t register_index = instruction.VRegA();
- HLongConstant* constant = GetLongConstant(instruction.VRegB_21s());
+ // Get 16 bits of constant value, sign extended to 64 bits.
+ int64_t value = instruction.VRegB_21s();
+ value <<= 48;
+ value >>= 48;
+ HLongConstant* constant = GetLongConstant(value);
UpdateLocal(register_index, constant);
break;
}
case Instruction::CONST_WIDE_32: {
int32_t register_index = instruction.VRegA();
- HLongConstant* constant = GetLongConstant(instruction.VRegB_31i());
+ // Get 32 bits of constant value, sign extended to 64 bits.
+ int64_t value = instruction.VRegB_31i();
+ value <<= 32;
+ value >>= 32;
+ HLongConstant* constant = GetLongConstant(value);
UpdateLocal(register_index, constant);
break;
}
@@ -361,27 +398,58 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
break;
}
- case Instruction::MOVE: {
+ case Instruction::CONST_WIDE_HIGH16: {
+ int32_t register_index = instruction.VRegA();
+ int64_t value = static_cast<int64_t>(instruction.VRegB_21h()) << 48;
+ HLongConstant* constant = GetLongConstant(value);
+ UpdateLocal(register_index, constant);
+ break;
+ }
+
+ // TODO: these instructions are also used to move floating point values, so what is
+ // the type (int or float)?
+ case Instruction::MOVE:
+ case Instruction::MOVE_FROM16:
+ case Instruction::MOVE_16: {
HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
UpdateLocal(instruction.VRegA(), value);
break;
}
- case Instruction::RETURN_VOID: {
- BuildReturn(instruction, Primitive::kPrimVoid);
+ // TODO: these instructions are also used to move floating point values, so what is
+ // the type (long or double)?
+ case Instruction::MOVE_WIDE:
+ case Instruction::MOVE_WIDE_FROM16:
+ case Instruction::MOVE_WIDE_16: {
+ HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimLong);
+ UpdateLocal(instruction.VRegA(), value);
break;
}
- case Instruction::IF_EQ: {
- If_22t<HEqual>(instruction, dex_offset, false);
+ case Instruction::MOVE_OBJECT:
+ case Instruction::MOVE_OBJECT_16:
+ case Instruction::MOVE_OBJECT_FROM16: {
+ HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimNot);
+ UpdateLocal(instruction.VRegA(), value);
break;
}
- case Instruction::IF_NE: {
- If_22t<HEqual>(instruction, dex_offset, true);
+ case Instruction::RETURN_VOID: {
+ BuildReturn(instruction, Primitive::kPrimVoid);
break;
}
+#define IF_XX(comparison, cond) \
+ case Instruction::IF_##cond: If_22t<comparison>(instruction, dex_offset); break; \
+ case Instruction::IF_##cond##Z: If_21t<comparison>(instruction, dex_offset); break
+
+ IF_XX(HEqual, EQ);
+ IF_XX(HNotEqual, NE);
+ IF_XX(HLessThan, LT);
+ IF_XX(HLessThanOrEqual, LE);
+ IF_XX(HGreaterThan, GT);
+ IF_XX(HGreaterThanOrEqual, GE);
+
case Instruction::GOTO:
case Instruction::GOTO_16:
case Instruction::GOTO_32: {
@@ -500,10 +568,10 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
}
case Instruction::MOVE_RESULT:
- case Instruction::MOVE_RESULT_WIDE: {
+ case Instruction::MOVE_RESULT_WIDE:
+ case Instruction::MOVE_RESULT_OBJECT:
UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
break;
- }
case Instruction::NOP:
break;