Add support for invoke-static in optimizing compiler.

Support is limited to calls without parameters and returning
void. For simplicity, we currently follow the Quick ABI.

Change-Id: I54805161141b7eac5959f1cae0dc138dd0b2e8a5
diff --git a/compiler/utils/assembler.h b/compiler/utils/assembler.h
index cd4fc12..3dc5b5d 100644
--- a/compiler/utils/assembler.h
+++ b/compiler/utils/assembler.h
@@ -48,6 +48,23 @@
   class X86Assembler;
 }
 
+class ExternalLabel {
+ public:
+  ExternalLabel(const char* name, uword address)
+      : name_(name), address_(address) {
+    DCHECK(name != nullptr);
+  }
+
+  const char* name() const { return name_; }
+  uword address() const {
+    return address_;
+  }
+
+ private:
+  const char* name_;
+  const uword address_;
+};
+
 class Label {
  public:
   Label() : position_(0) {}
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc
index db8956d..3c8a16a 100644
--- a/compiler/utils/x86/assembler_x86.cc
+++ b/compiler/utils/x86/assembler_x86.cc
@@ -54,6 +54,16 @@
 }
 
 
+void X86Assembler::call(const ExternalLabel& label) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  intptr_t call_start = buffer_.GetPosition();
+  EmitUint8(0xE8);
+  EmitInt32(label.address());
+  static const intptr_t kCallExternalLabelSize = 5;
+  DCHECK_EQ((buffer_.GetPosition() - call_start), kCallExternalLabelSize);
+}
+
+
 void X86Assembler::pushl(Register reg) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0x50 + reg);
diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h
index e284d8c..67356af 100644
--- a/compiler/utils/x86/assembler_x86.h
+++ b/compiler/utils/x86/assembler_x86.h
@@ -227,6 +227,7 @@
   void call(Register reg);
   void call(const Address& address);
   void call(Label* label);
+  void call(const ExternalLabel& label);
 
   void pushl(Register reg);
   void pushl(const Address& address);