Subzero: Partial implementation of global initializers.

This is still missing a couple things:

1. It only supports flat arrays and zeroinitializers.  Arrays of structs are not yet supported.

2. Initializers can't yet contain relocatables, e.g. the address of another global.Mod

Some changes are made to work around an llvm-mc assembler bug.  When assembling using intel syntax, llvm-mc doesn't correctly parse symbolic constants or add relocation entries in some circumstances.  Call instructions work, and use in a memory operand works, e.g. mov eax, [ArrayBase+4*ecx].  To work around this, we adjust legalize() to not allow ConstantRelocatable by default, except for memory operands and when called from lowerCall(), so the relocatable ends up being the source operand of a mov instruction.  Then, the mov emit routine actually emits an lea instruction for such moves.

A few lit tests needed to be adjusted to make szdiff work properly with respect to global initializers.

In the new cross test, the driver calls test code that returns a pointer to an array with a global initializer, and the driver compares the arrays returned by llc and Subzero.

BUG= none
R=jvoung@chromium.org

Review URL: https://codereview.chromium.org/358013003
diff --git a/tests_lit/llvm2ice_tests/globalinit.pnacl.ll b/tests_lit/llvm2ice_tests/globalinit.pnacl.ll
new file mode 100644
index 0000000..593c5e4
--- /dev/null
+++ b/tests_lit/llvm2ice_tests/globalinit.pnacl.ll
@@ -0,0 +1,103 @@
+; Test of global initializers.
+
+; RUN: %llvm2ice --verbose inst %s | FileCheck %s
+; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s
+; RUN: %llvm2iceinsts %s | %szdiff %s | FileCheck --check-prefix=DUMP %s
+
+@PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
+; CHECK: .data
+; CHECK-NEXT: .align 4
+; CHECK-NEXT: PrimitiveInit:
+; CHECK-NEXT: .byte
+; CHECK: .size PrimitiveInit, 4
+
+@PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4
+; CHECK: .section .rodata,"a",@progbits
+; CHECK-NEXT: .align 4
+; CHECK-NEXT: PrimitiveInitConst:
+; CHECK-NEXT: .byte
+; CHECK: .size PrimitiveInitConst, 4
+
+@ArrayInit = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4
+; CHECK: .data
+; CHECK-NEXT: .align 4
+; CHECK-NEXT: ArrayInit:
+; CHECK-NEXT: .byte
+; CHECK: .size ArrayInit, 20
+
+@ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
+; CHECK: .data
+; CHECK-NEXT: .align 4
+; CHECK-NEXT: ArrayInitPartial:
+; CHECK-NEXT: .byte
+; CHECK: .size ArrayInitPartial, 40
+
+@PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4
+; CHECK: .data
+; CHECK-NEXT: .comm PrimitiveInitStatic, 4, 4
+; CHECK-NEXT: .local PrimitiveInitStatic
+
+@PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4
+; CHECK: .data
+; CHECK-NEXT: .comm PrimitiveUninit, 4, 4
+; CHECK-NEXT: .local PrimitiveUninit
+
+@ArrayUninit = internal global [20 x i8] zeroinitializer, align 4
+; CHECK: .data
+; CHECK-NEXT: .comm ArrayUninit, 20, 4
+; CHECK-NEXT: .local ArrayUninit
+
+@ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8
+; CHECK: .section .rodata,"a",@progbits
+; CHECK-NEXT: .align 8
+; CHECK-NEXT: ArrayUninitConstDouble:
+; CHECK-NEXT: .zero 200
+; CHECK-NEXT: .size ArrayUninitConstDouble, 200
+
+@ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4
+; CHECK: .section .rodata,"a",@progbits
+; CHECK-NEXT: .align 4
+; CHECK-NEXT: ArrayUninitConstInt:
+; CHECK-NEXT: .zero 20
+; CHECK-NEXT: .size ArrayUninitConstInt, 20
+
+@__init_array_start = internal constant [0 x i8] zeroinitializer, align 4
+@__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4
+@__tls_template_start = internal constant [0 x i8] zeroinitializer, align 8
+@__tls_template_alignment = internal constant [4 x i8] c"\01\00\00\00", align 4
+
+define internal i32 @main(i32 %argc, i32 %argv) {
+entry:
+  %expanded1 = ptrtoint [4 x i8]* @PrimitiveInit to i32
+  call void @use(i32 %expanded1)
+  %expanded3 = ptrtoint [4 x i8]* @PrimitiveInitConst to i32
+  call void @use(i32 %expanded3)
+  %expanded5 = ptrtoint [4 x i8]* @PrimitiveInitStatic to i32
+  call void @use(i32 %expanded5)
+  %expanded7 = ptrtoint [4 x i8]* @PrimitiveUninit to i32
+  call void @use(i32 %expanded7)
+  %expanded9 = ptrtoint [20 x i8]* @ArrayInit to i32
+  call void @use(i32 %expanded9)
+  %expanded11 = ptrtoint [40 x i8]* @ArrayInitPartial to i32
+  call void @use(i32 %expanded11)
+  %expanded13 = ptrtoint [20 x i8]* @ArrayUninit to i32
+  call void @use(i32 %expanded13)
+  ret i32 0
+}
+; CHECK: entry:
+
+declare void @use(i32)
+
+define internal i32 @nacl_tp_tdb_offset(i32 %__0) {
+entry:
+  ret i32 0
+}
+
+define internal i32 @nacl_tp_tls_offset(i32 %size) {
+entry:
+  %result = sub i32 0, %size
+  ret i32 %result
+}
+
+; ERRORS-NOT: ICE translation error
+; DUMP-NOT: SZ