gollvm: refactor unit tests to support multiple architectures

The previous unit test cases are written for amd64 specifically. In order
to support multiple architectures, this CL makes the following adjustments
to the unit test framework:
1, for architecture-independent unit tests, replace TEST with TEST_P and take
   calling convention ID as parameter, run on all supported architectures.
2, For architecture-dependent tests, write a separate test function for each
   supported architecture.

Change-Id: Ic2b140484338e6f8711e2b18a1946b4c24b65c8a
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/211838
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/README.md b/README.md
index 86bbe8a..8a98ebf 100644
--- a/README.md
+++ b/README.md
@@ -213,7 +213,7 @@
   Type *ft = Type::getFloatTy(C);
   Type *dt = Type::getDoubleTy(C);
 
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  std::unique_ptr<Backend> be(go_get_backend(C, llvm::CallingConv::X86_64_SysV));
   Btype *c32 = be->complex_type(64);
   ASSERT_TRUE(c32 != NULL);
   ASSERT_EQ(c32->type(), mkTwoFieldLLvmStruct(C, ft, ft));
diff --git a/bridge/go-llvm-backend.h b/bridge/go-llvm-backend.h
index bb0b5c8..9c7f7e4 100644
--- a/bridge/go-llvm-backend.h
+++ b/bridge/go-llvm-backend.h
@@ -19,6 +19,6 @@
 
 class Backend;
 
-extern Backend *go_get_backend(llvm::LLVMContext &Context);
+extern Backend *go_get_backend(llvm::LLVMContext &Context, llvm::CallingConv::ID cconv);
 
 #endif // !defined(GO_LLVM_BACKEND_H)
diff --git a/bridge/go-llvm.cpp b/bridge/go-llvm.cpp
index 7db9f44..ee1c747 100644
--- a/bridge/go-llvm.cpp
+++ b/bridge/go-llvm.cpp
@@ -4073,6 +4073,6 @@
 
 // Return a new backend generator.
 
-Backend *go_get_backend(llvm::LLVMContext &context) {
-  return new Llvm_backend(context, nullptr, nullptr, 0);
+Backend *go_get_backend(llvm::LLVMContext &context, llvm::CallingConv::ID cconv) {
+  return new Llvm_backend(context, nullptr, nullptr, 0, cconv);
 }
diff --git a/unittests/BackendCore/BackendArrayStruct.cpp b/unittests/BackendCore/BackendArrayStruct.cpp
index 4361d51..1b5cc6b 100644
--- a/unittests/BackendCore/BackendArrayStruct.cpp
+++ b/unittests/BackendCore/BackendArrayStruct.cpp
@@ -17,8 +17,20 @@
 
 namespace {
 
-TEST(BackendArrayStructTests, TestStructFieldExprs) {
-  FcnTestHarness h("foo");
+class BackendArrayStructTests
+    : public testing::TestWithParam<llvm::CallingConv::ID> {};
+
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendArrayStructTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendArrayStructTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendArrayStructTests, TestStructFieldExprs) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   //
@@ -50,7 +62,7 @@
   h.mkAssign(vex, fex);
 
   // var b2 bool
-  // loc1.b = &b2
+  // loc1.f1 = &b2
   Bvariable *b2 = h.mkLocal("b2", bt);
   Bexpression *lvex = be->var_expression(loc1, loc);
   Bexpression *bfex = be->struct_field_expression(lvex, 0, loc);
@@ -58,7 +70,6 @@
   Bexpression *adb2 = be->address_expression(b2ex, loc);
   h.mkAssign(bfex, adb2);
 
-  // var b2 bool
   // loc2.f2 = 2 (equivalent to (*loc2).f2 = 2)
   Bexpression *lvexi = be->var_expression(loc2, loc);
   bool knValid = false;
@@ -68,20 +79,20 @@
   h.mkAssign(bfex2, bc2);
 
   const char *exp = R"RAW_RESULT(
-      %cast.0 = bitcast { i8*, i32 }* %loc1 to i8*
-      %cast.1 = bitcast { i8*, i32 }* @const.0 to i8*
-      call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 16, i1 false)
-      store { i8*, i32 }* %loc1, { i8*, i32 }** %loc2
-      store i32 0, i32* %x
-      %field.0 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc1, i32 0, i32 1
-      %loc1.field.ld.0 = load i32, i32* %field.0
-      store i32 %loc1.field.ld.0, i32* %x
-      store i8 0, i8* %b2
-      %field.1 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc1, i32 0, i32 0
-      store i8* %b2, i8** %field.1
-      %loc2.ld.0 = load { i8*, i32 }*, { i8*, i32 }** %loc2
-      %field.2 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc2.ld.0, i32 0, i32 1
-      store i32 2, i32* %field.2
+    %cast.0 = bitcast { i8*, i32 }* %loc1 to i8*
+    %cast.1 = bitcast { i8*, i32 }* @const.0 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 16, i1 false)
+    store { i8*, i32 }* %loc1, { i8*, i32 }** %loc2
+    store i32 0, i32* %x
+    %field.0 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc1, i32 0, i32 1
+    %loc1.field.ld.0 = load i32, i32* %field.0
+    store i32 %loc1.field.ld.0, i32* %x
+    store i8 0, i8* %b2
+    %field.1 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc1, i32 0, i32 0
+    store i8* %b2, i8** %field.1
+    %loc2.ld.0 = load { i8*, i32 }*, { i8*, i32 }** %loc2
+    %field.2 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc2.ld.0, i32 0, i32 1
+    store i32 2, i32* %field.2
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -91,9 +102,10 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendArrayStructTests, TestStructFieldExprs2) {
+TEST_P(BackendArrayStructTests, TestStructFieldExprs2) {
+  auto cc = GetParam();
   // Testing struct field expression for composites.
-  FcnTestHarness h;
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty);
@@ -163,9 +175,10 @@
   EXPECT_TRUE(isOK && "Block does not have expected contents");
 }
 
-TEST(BackendArrayStructTests, TestArrayIndexingExprs) {
+TEST_P(BackendArrayStructTests, TestArrayIndexingExprs) {
+  auto cc = GetParam();
   // Testing array indexing expression for composites.
-  FcnTestHarness h;
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty);
@@ -247,7 +260,8 @@
       %index.5 = getelementptr [4 x i64], [4 x i64]* @const.0, i32 0, i64 %x.ld.0
       %.index.ld.1 = load i64, i64* %index.5
       store i64 %.index.ld.1, i64* %w
-      ret void    }
+      ret void
+    }
   )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
@@ -257,9 +271,9 @@
   EXPECT_TRUE(isOK && "Block does not have expected contents");
 }
 
-TEST(BackendArrayStructTests, CreateArrayConstructionExprs) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendArrayStructTests, CreateArrayConstructionExprs) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   // var aa [4]int64 = { 4, 3, 2, 1 }
@@ -318,8 +332,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendArrayStructTests, CreateStructConstructionExprs) {
-  FcnTestHarness h("foo");
+TEST_P(BackendArrayStructTests, CreateStructConstructionExprs) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -339,8 +354,7 @@
   std::vector<Bexpression *> vals1;
   vals1.push_back(be->zero_expression(pbi32t));
   vals1.push_back(mkInt32Const(be, int32_t(101)));
-  Bexpression *scon1 =
-      be->constructor_expression(s2t, vals1, loc);
+  Bexpression *scon1 = be->constructor_expression(s2t, vals1, loc);
   Bvariable *loc1 = h.mkLocal("loc1", s2t, scon1);
 
   // var loc2 X = { &param1, loc1.f2 }
@@ -356,15 +370,15 @@
   h.mkLocal("loc2", s2t, scon2);
 
   const char *exp = R"RAW_RESULT(
-      %cast.0 = bitcast { i32*, i32 }* %loc1 to i8*
-      %cast.1 = bitcast { i32*, i32 }* @const.0 to i8*
-      call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 16, i1 false)
-      %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc1, i32 0, i32 1
-      %loc1.field.ld.0 = load i32, i32* %field.0
-      %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc2, i32 0, i32 0
-      store i32* %param1.addr, i32** %field.1
-      %field.2 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc2, i32 0, i32 1
-      store i32 %loc1.field.ld.0, i32* %field.2
+    %cast.0 = bitcast { i32*, i32 }* %loc1 to i8*
+    %cast.1 = bitcast { i32*, i32 }* @const.0 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 16, i1 false)
+    %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc1, i32 0, i32 1
+    %loc1.field.ld.0 = load i32, i32* %field.0
+    %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc2, i32 0, i32 0
+    store i32* %param1.addr, i32** %field.1
+    %field.2 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc2, i32 0, i32 1
+    store i32 %loc1.field.ld.0, i32* %field.2
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -374,8 +388,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendArrayStructTests, CreateNestedStructConstructionExprs) {
-  FcnTestHarness h("foo");
+TEST_P(BackendArrayStructTests, CreateNestedStructConstructionExprs) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -401,32 +416,30 @@
   Bexpression *adp = be->address_expression(ve1, loc);
   vals1.push_back(adp);
   vals1.push_back(mkInt32Const(be, int32_t(3)));
-  Bexpression *scon1 =
-      be->constructor_expression(sxt, vals1, loc);
+  Bexpression *scon1 = be->constructor_expression(sxt, vals1, loc);
   std::vector<Bexpression *> vals2;
   vals2.push_back(scon1);
   Bexpression *ci3 = mkInt32Const(be, int32_t(3));
   vals2.push_back(be->convert_expression(bf32t, ci3, loc));
-  Bexpression *scon2 =
-      be->constructor_expression(syt, vals2, loc);
+  Bexpression *scon2 = be->constructor_expression(syt, vals2, loc);
   Bvariable *loc1 = h.mkLocal("loc1", syt);
   Bexpression *vex = be->var_expression(loc1, loc);
   h.mkAssign(vex, scon2);
 
   const char *exp = R"RAW_RESULT(
-  %cast.0 = bitcast { { i32*, i32 }, float }* %loc1 to i8*
-  %cast.1 = bitcast { { i32*, i32 }, float }* @const.0 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 24, i1 false)
-  %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %tmp.0, i32 0, i32 0
-  store i32* %param1.addr, i32** %field.0
-  %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %tmp.0, i32 0, i32 1
-  store i32 3, i32* %field.1
-  %field.2 = getelementptr inbounds { { i32*, i32 }, float }, { { i32*, i32 }, float }* %loc1, i32 0, i32 0
-  %cast.2 = bitcast { i32*, i32 }* %field.2 to i8*
-  %cast.3 = bitcast { i32*, i32 }* %tmp.0 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 %cast.3, i64 16, i1 false)
-  %field.3 = getelementptr inbounds { { i32*, i32 }, float }, { { i32*, i32 }, float }* %loc1, i32 0, i32 1
-  store float 3.000000e+00, float* %field.3
+    %cast.0 = bitcast { { i32*, i32 }, float }* %loc1 to i8*
+    %cast.1 = bitcast { { i32*, i32 }, float }* @const.0 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 24, i1 false)
+    %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %tmp.0, i32 0, i32 0
+    store i32* %param1.addr, i32** %field.0
+    %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %tmp.0, i32 0, i32 1
+    store i32 3, i32* %field.1
+    %field.2 = getelementptr inbounds { { i32*, i32 }, float }, { { i32*, i32 }, float }* %loc1, i32 0, i32 0
+    %cast.2 = bitcast { i32*, i32 }* %field.2 to i8*
+    %cast.3 = bitcast { i32*, i32 }* %tmp.0 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 %cast.3, i64 16, i1 false)
+    %field.3 = getelementptr inbounds { { i32*, i32 }, float }, { { i32*, i32 }, float }* %loc1, i32 0, i32 1
+    store float 3.000000e+00, float* %field.3
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -436,8 +449,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendArrayStructTests, CreateStructConstructionExprs2) {
-  FcnTestHarness h;
+TEST_P(BackendArrayStructTests, CreateStructConstructionExprs2) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
 
   Btype *bi32t = be->integer_type(false, 32);
@@ -459,17 +473,16 @@
   std::vector<Bexpression *> vals;
   vals.push_back(be->var_expression(p1, loc));
   vals.push_back(mkInt32Const(be, int32_t(101)));
-  Bexpression *scon =
-      be->constructor_expression(s2t, vals, loc);
+  Bexpression *scon = be->constructor_expression(s2t, vals, loc);
   h.mkAssign(dex, scon);
 
   const char *exp = R"RAW_RESULT(
-      %p0.ld.0 = load { i32*, i32 }*, { i32*, i32 }** %p0.addr
-      %p1.ld.0 = load i32*, i32** %p1.addr
-      %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %p0.ld.0, i32 0, i32 0
-      store i32* %p1.ld.0, i32** %field.0
-      %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %p0.ld.0, i32 0, i32 1
-      store i32 101, i32* %field.1
+    %p0.ld.0 = load { i32*, i32 }*, { i32*, i32 }** %p0.addr
+    %p1.ld.0 = load i32*, i32** %p1.addr
+    %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %p0.ld.0, i32 0, i32 0
+    store i32* %p1.ld.0, i32** %field.0
+    %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %p0.ld.0, i32 0, i32 1
+    store i32 101, i32* %field.1
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -479,9 +492,10 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendArrayStructTests, CreateStructConstructionExprs3) {
+TEST_P(BackendArrayStructTests, CreateStructConstructionExprs3) {
+  auto cc = GetParam();
   // Test struct construction involving global variables.
-  FcnTestHarness h("foo");
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -531,9 +545,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendArrayStructTests, CreateArrayIndexingExprs) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendArrayStructTests, CreateArrayIndexingExprs) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   // var aa [4]int64 = { 4, 3, 2, 1 }
@@ -571,17 +585,17 @@
   h.mkAssign(aa4, aa3);
 
   const char *exp = R"RAW_RESULT(
-  %cast.0 = bitcast [4 x i64]* %aa to i8*
-  %cast.1 = bitcast [4 x i64]* @const.0 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 32, i1 false)
-  %index.0 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i32 1
-  %aa.index.ld.0 = load i64, i64* %index.0
-  %index.1 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 %aa.index.ld.0
-  %index.2 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 3
-  %aa.index.ld.1 = load i64, i64* %index.2
-  %index.3 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 %aa.index.ld.1
-  %aa.index.ld.2 = load i64, i64* %index.3
-  store i64 %aa.index.ld.2, i64* %index.1
+    %cast.0 = bitcast [4 x i64]* %aa to i8*
+    %cast.1 = bitcast [4 x i64]* @const.0 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 32, i1 false)
+    %index.0 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i32 1
+    %aa.index.ld.0 = load i64, i64* %index.0
+    %index.1 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 %aa.index.ld.0
+    %index.2 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 3
+    %aa.index.ld.1 = load i64, i64* %index.2
+    %index.3 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 %aa.index.ld.1
+    %aa.index.ld.2 = load i64, i64* %index.3
+    store i64 %aa.index.ld.2, i64* %index.1
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -591,9 +605,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendArrayStructTests, CreateComplexIndexingAndFieldExprs) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendArrayStructTests, CreateComplexIndexingAndFieldExprs) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
 
   // Create type that incorporates structures, arrays, and pointers:
   //
@@ -640,7 +654,7 @@
     Bexpression *bi64five = mkInt64Const(be, 5);
     h.mkAssign(fx, bi64five);
 
-  const char *exp = R"RAW_RESULT(
+    const char *exp = R"RAW_RESULT(
       %cast.0 = bitcast [10 x { i8, [4 x { i64, i64 }*], i8 }*]* %t1 to i8*
       %cast.1 = bitcast [10 x { i8, [4 x { i64, i64 }*], i8 }*]* @const.0 to i8*
       call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 80, i1 false)
@@ -651,11 +665,10 @@
       %.field.index.ld.0 = load { i64, i64 }*, { i64, i64 }** %index.1
       %field.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %.field.index.ld.0, i32 0, i32 0
       store i64 5, i64* %field.1
-  )RAW_RESULT";
+    )RAW_RESULT";
 
-  bool isOK = h.expectBlock(exp);
-  EXPECT_TRUE(isOK && "Block does not have expected contents");
-
+    bool isOK = h.expectBlock(exp);
+    EXPECT_TRUE(isOK && "Block does not have expected contents");
   }
 
   h.newBlock();
@@ -673,7 +686,7 @@
     Bexpression *fx = be->struct_field_expression(iar3, 1, loc);
     h.mkLocal("q", bi64t, fx);
 
-  const char *exp = R"RAW_RESULT(
+    const char *exp = R"RAW_RESULT(
       %index.2 = getelementptr [10 x { i8, [4 x { i64, i64 }*], i8 }*], [10 x { i8, [4 x { i64, i64 }*], i8 }*]* %t1, i32 0, i32 0
       %t1.index.ld.1 = load { i8, [4 x { i64, i64 }*], i8 }*, { i8, [4 x { i64, i64 }*], i8 }** %index.2
       %field.2 = getelementptr inbounds { i8, [4 x { i64, i64 }*], i8 }, { i8, [4 x { i64, i64 }*], i8 }* %t1.index.ld.1, i32 0, i32 1
@@ -682,19 +695,19 @@
       %field.3 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %.field.index.ld.1, i32 0, i32 1
       %.field.ld.0 = load i64, i64* %field.3
       store i64 %.field.ld.0, i64* %q
-  )RAW_RESULT";
+    )RAW_RESULT";
 
-  bool isOK = h.expectBlock(exp);
-  EXPECT_TRUE(isOK && "Block does not have expected contents");
-
+    bool isOK = h.expectBlock(exp);
+    EXPECT_TRUE(isOK && "Block does not have expected contents");
   }
 
   bool broken = h.finish(PreserveDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendArrayStructTests, TestStructAssignment) {
-  FcnTestHarness h("foo");
+TEST_P(BackendArrayStructTests, TestStructAssignment) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   // type T1 struct { f1 bool }
@@ -724,25 +737,25 @@
   h.mkAssign(ve3, ve4);
 
   const char *exp = R"RAW_RESULT(
-%cast.0 = bitcast { i8* }* %x1 to i8*
-  %cast.1 = bitcast { i8* }* @const.0 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 8, i1 false)
-  %cast.2 = bitcast { i8* }* %y1 to i8*
-  %cast.3 = bitcast { i8* }* @const.0 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 %cast.3, i64 8, i1 false)
-  %cast.4 = bitcast { i64, i64, i64, i64, i64, i64 }* %x2 to i8*
-  %cast.5 = bitcast { i64, i64, i64, i64, i64, i64 }* @const.1 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.4, i8* align 8 %cast.5, i64 48, i1 false)
-  %cast.6 = bitcast { i64, i64, i64, i64, i64, i64 }* %y2 to i8*
-  %cast.7 = bitcast { i64, i64, i64, i64, i64, i64 }* @const.1 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.6, i8* align 8 %cast.7, i64 48, i1 false)
-  %cast.8 = bitcast { i8* }* %x1 to i8*
-  %cast.9 = bitcast { i8* }* %y1 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.8, i8* align 8 %cast.9, i64 8, i1 false)
-  %cast.10 = bitcast { i64, i64, i64, i64, i64, i64 }* %x2 to i8*
-  %cast.11 = bitcast { i64, i64, i64, i64, i64, i64 }* %y2 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.10, i8* align 8 %cast.11, i64 48, i1 false)
-   )RAW_RESULT";
+    %cast.0 = bitcast { i8* }* %x1 to i8*
+    %cast.1 = bitcast { i8* }* @const.0 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 8, i1 false)
+    %cast.2 = bitcast { i8* }* %y1 to i8*
+    %cast.3 = bitcast { i8* }* @const.0 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 %cast.3, i64 8, i1 false)
+    %cast.4 = bitcast { i64, i64, i64, i64, i64, i64 }* %x2 to i8*
+    %cast.5 = bitcast { i64, i64, i64, i64, i64, i64 }* @const.1 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.4, i8* align 8 %cast.5, i64 48, i1 false)
+    %cast.6 = bitcast { i64, i64, i64, i64, i64, i64 }* %y2 to i8*
+    %cast.7 = bitcast { i64, i64, i64, i64, i64, i64 }* @const.1 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.6, i8* align 8 %cast.7, i64 48, i1 false)
+    %cast.8 = bitcast { i8* }* %x1 to i8*
+    %cast.9 = bitcast { i8* }* %y1 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.8, i8* align 8 %cast.9, i64 8, i1 false)
+    %cast.10 = bitcast { i64, i64, i64, i64, i64, i64 }* %x2 to i8*
+    %cast.11 = bitcast { i64, i64, i64, i64, i64, i64 }* %y2 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.10, i8* align 8 %cast.11, i64 48, i1 false)
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -751,9 +764,10 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendArrayStructTests, TestStructFieldAddressExpr) {
+TEST_P(BackendArrayStructTests, TestStructFieldAddressExpr) {
+  auto cc = GetParam();
   // Test address expression of struct field.
-  FcnTestHarness h("foo");
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -790,7 +804,7 @@
     %field.0 = getelementptr inbounds { i32 }, { i32 }* %t1, i32 0, i32 0
     store i32* %field.0, i32** %a1
     store i32* getelementptr inbounds ({ i32 }, { i32 }* @t2, i32 0, i32 0), i32** %a2
-   )RAW_RESULT";
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -799,4 +813,4 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendCABIOracleTests.cpp b/unittests/BackendCore/BackendCABIOracleTests.cpp
index 5d7e1b6..fc6ef51 100644
--- a/unittests/BackendCore/BackendCABIOracleTests.cpp
+++ b/unittests/BackendCore/BackendCABIOracleTests.cpp
@@ -18,9 +18,22 @@
 
 namespace {
 
-TEST(BackendCABIOracleTests, Basic) {
+class BackendCABIOracleTests
+    : public testing::TestWithParam<llvm::CallingConv::ID> {};
+
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendCABIOracleTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendCABIOracleTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendCABIOracleTests, Basic) {
   LLVMContext C;
-  std::unique_ptr<Llvm_backend> bep(new Llvm_backend(C, nullptr, nullptr, 0));
+  auto cc = GetParam();
+  std::unique_ptr<Llvm_backend> bep(
+      new Llvm_backend(C, nullptr, nullptr, 0, cc));
   Llvm_backend *be = bep.get();
 
   Btype *bi8t = be->integer_type(false, 8);
@@ -56,9 +69,10 @@
   }
 }
 
-TEST(BackendCABIOracleTests, Extended) {
+TEST(BackendCABIOracleTests, ExtendedAmd64) {
   LLVMContext C;
-  std::unique_ptr<Llvm_backend> bep(new Llvm_backend(C, nullptr, nullptr, 0));
+  std::unique_ptr<Llvm_backend> bep(
+      new Llvm_backend(C, nullptr, nullptr, 0, llvm::CallingConv::X86_64_SysV));
   Llvm_backend *be = bep.get();
 
   Btype *bi8t = be->integer_type(false, 8);
@@ -103,100 +117,100 @@
   Btype *nt = nullptr;
   std::vector<FcnItem> items = {
 
-    // 1
-    FcnItem( {  }, {  },
-             "Return: Ignore { void } sigOffset: -1 "
-             "Param 1: Direct AttrNest { i8* } sigOffset: 0",
-             "void (i8*)"),
+      // 1
+      FcnItem( { }, { },
+              "Return: Ignore { void } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0",
+              "void (i8*)"),
 
-    // 2
-    FcnItem( { bi8t }, { },
-             "Return: Direct AttrSext { i8 } sigOffset: -1 "
-             "Param 1: Direct AttrNest { i8* } sigOffset: 0",
-             "i8 (i8*)"),
+      // 2
+      FcnItem( { bi8t }, { },
+              "Return: Direct AttrSext { i8 } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0",
+              "i8 (i8*)"),
 
-    // 3
-    FcnItem( {  }, { bi8t },
-             "Return: Ignore { void } sigOffset: -1 "
-             "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
-             "Param 2: Direct AttrSext { i8 } sigOffset: 1",
-             "void (i8*, i8)"),
+      // 3
+      FcnItem( { }, { bi8t },
+              "Return: Ignore { void } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+              "Param 2: Direct AttrSext { i8 } sigOffset: 1",
+              "void (i8*, i8)"),
 
-    // 4
-    FcnItem( {  }, { st5, bpf64t },
-             "Return: Ignore { void } sigOffset: -1 "
-             "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
-             "Param 2: Direct { float } sigOffset: 1 "
-             "Param 3: Direct { double* } sigOffset: 2",
-             "void (i8*, float, double*)"),
+      // 4
+      FcnItem( { }, { st5, bpf64t },
+              "Return: Ignore { void } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+              "Param 2: Direct { float } sigOffset: 1 "
+              "Param 3: Direct { double* } sigOffset: 2",
+              "void (i8*, float, double*)"),
 
-    // 5
-    FcnItem({ bi8t, bf64t }, { bi8t, bu8t, st0 },
-            "Return: Direct { { i8, double } } sigOffset: -1 "
-            "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
-            "Param 2: Direct AttrSext { i8 } sigOffset: 1 "
-            "Param 3: Direct AttrZext { i8 } sigOffset: 2 "
-            "Param 4: Ignore { void } sigOffset: -1",
-            "{ i8, double } (i8*, i8, i8)"),
+      // 5
+      FcnItem({ bi8t, bf64t }, { bi8t, bu8t, st0 },
+              "Return: Direct { { i8, double } } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+              "Param 2: Direct AttrSext { i8 } sigOffset: 1 "
+              "Param 3: Direct AttrZext { i8 } sigOffset: 2 "
+              "Param 4: Ignore { void } sigOffset: -1",
+              "{ i8, double } (i8*, i8, i8)"),
 
-    // 6
-    FcnItem({ st2 }, { st2, st0, st4, st1 },
-            "Return: Direct { { double, double } } sigOffset: -1 "
-            "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
-            "Param 2: Direct { double, double } sigOffset: 1 "
-            "Param 3: Ignore { void } sigOffset: -1 "
-            "Param 4: Direct { <2 x float> } sigOffset: 3 "
-            "Param 5: Direct { i64 } sigOffset: 4 ",
-            "{ double, double } (i8*, double, double, <2 x float>, i64)"),
+      // 6
+      FcnItem({ st2 }, { st2, st0, st4, st1 },
+              "Return: Direct { { double, double } } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+              "Param 2: Direct { double, double } sigOffset: 1 "
+              "Param 3: Ignore { void } sigOffset: -1 "
+              "Param 4: Direct { <2 x float> } sigOffset: 3 "
+              "Param 5: Direct { i64 } sigOffset: 4 ",
+              "{ double, double } (i8*, double, double, <2 x float>, i64)"),
 
-    // 7
-    FcnItem({ st3 }, { st3, st0, bu8t },
-            "Return: Indirect AttrStructReturn { { { double, double }, i8 }* } sigOffset: 0 "
-            "Param 1: Direct AttrNest { i8* } sigOffset: 1 "
-            "Param 2: Indirect AttrByVal { { { double, double }, i8 }* } sigOffset: 2 "
-            "Param 3: Ignore { void } sigOffset: -1 "
-            "Param 4: Direct AttrZext { i8 } sigOffset: 3 ",
-            "void ({ { double, double }, i8 }*, i8*, "
-            "{ { double, double }, i8 }*, i8)"),
+      // 7
+      FcnItem({ st3 }, { st3, st0, bu8t },
+              "Return: Indirect AttrStructReturn { { { double, double }, i8 }* } sigOffset: 0 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 1 "
+              "Param 2: Indirect AttrByVal { { { double, double }, i8 }* } sigOffset: 2 "
+              "Param 3: Ignore { void } sigOffset: -1 "
+              "Param 4: Direct AttrZext { i8 } sigOffset: 3 ",
+              "void ({ { double, double }, i8 }*, i8*, "
+              "{ { double, double }, i8 }*, i8)"),
 
-    // 8
-    FcnItem( { st6 }, { st6, st6 },
-             "Return: Direct { { i64, i64 } } sigOffset: -1 "
-             "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
-             "Param 2: Direct { i64, i64 } sigOffset: 1 "
-             "Param 3: Direct { i64, i64 } sigOffset: 3",
-             "{ i64, i64 } (i8*, i64, i64, i64, i64)"),
+      // 8
+      FcnItem( { st6 }, { st6, st6 },
+              "Return: Direct { { i64, i64 } } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+              "Param 2: Direct { i64, i64 } sigOffset: 1 "
+              "Param 3: Direct { i64, i64 } sigOffset: 3",
+              "{ i64, i64 } (i8*, i64, i64, i64, i64)"),
 
-    // 9
-    FcnItem( { st8 }, { st8 },
-             "Return: Direct { { i64, i32 } } sigOffset: -1 "
-             "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
-             "Param 2: Direct { i64, i32 } sigOffset: 1",
-             "{ i64, i32 } (i8*, i64, i32)"),
+      // 9
+      FcnItem( { st8 }, { st8 },
+              "Return: Direct { { i64, i32 } } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+              "Param 2: Direct { i64, i32 } sigOffset: 1",
+              "{ i64, i32 } (i8*, i64, i32)"),
 
-    // 10
-    FcnItem( { at0 }, { at1 },
-             "Return: Ignore { void } sigOffset: -1 "
-             "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
-             "Param 2: Direct { i32 } sigOffset: 1",
-             "void (i8*, i32)"),
+      // 10
+      FcnItem( { at0 }, { at1 },
+              "Return: Ignore { void } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+              "Param 2: Direct { i32 } sigOffset: 1",
+              "void (i8*, i32)"),
 
-    // 11
-    FcnItem( { at2 }, { at3 },
-             "Return: Direct { { i64, i32 } } sigOffset: -1 "
-             "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
-             "Param 2: Direct { i64, i64 } sigOffset: 1",
-             "{ i64, i32 } (i8*, i64, i64)"),
+      // 11
+      FcnItem( { at2 }, { at3 },
+              "Return: Direct { { i64, i32 } } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+              "Param 2: Direct { i64, i64 } sigOffset: 1",
+              "{ i64, i32 } (i8*, i64, i64)"),
 
-    // 12
-    // Make sure pointerness is preserved.
-    FcnItem( { stip }, { stii, stpp, stpi },
-             "Return: Direct { { i64, i8* } } sigOffset: -1 "
-             "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
-             "Param 2: Direct { i64, i64 } sigOffset: 1 "
-             "Param 3: Direct { i8*, i8* } sigOffset: 3 "
-             "Param 4: Direct { i8*, i64 } sigOffset: 5",
-             "{ i64, i8* } (i8*, i64, i64, i8*, i8*, i8*, i64)"),
+      // 12
+      // Make sure pointerness is preserved.
+      FcnItem( { stip }, { stii, stpp, stpi },
+              "Return: Direct { { i64, i8* } } sigOffset: -1 "
+              "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+              "Param 2: Direct { i64, i64 } sigOffset: 1 "
+              "Param 3: Direct { i8*, i8* } sigOffset: 3 "
+              "Param 4: Direct { i8*, i64 } sigOffset: 5",
+              "{ i64, i8* } (i8*, i64, i64, i8*, i8*, i8*, i64)"),
   };
 
   unsigned count = 1;
@@ -214,7 +228,8 @@
     BFunctionType *bft = t->castToBFunctionType();
     CABIOracle cab(bft, be->typeManager());
 
-    { std::string reason;
+    {
+      std::string reason;
       bool equal = difftokens(item.expDump, cab.toString(), reason);
       EXPECT_EQ("pass", equal ? "pass" : reason);
       if (!equal) {
@@ -223,7 +238,8 @@
         std::cerr << "act:\n" << cab.toString() << "\n";
       }
     }
-    { std::string reason;
+    {
+      std::string reason;
       std::string result(repr(cab.getFunctionTypeForABI()));
       bool equal = difftokens(item.expTyp, result, reason);
       EXPECT_EQ("pass", equal ? "pass" : reason);
@@ -237,8 +253,8 @@
   }
 }
 
-TEST(BackendCABIOracleTests, RecursiveCall1) {
-  FcnTestHarness h;
+TEST(BackendCABIOracleTests, RecursiveCall1Amd64) {
+  FcnTestHarness h(llvm::CallingConv::X86_64_SysV);
   Llvm_backend *be = h.be();
 
   // type s1 struct {
@@ -250,15 +266,16 @@
   //   f1, f2 float32
   // }
   // type s3 struct {
-  //   f1, f2 s1
+  //   f1, s1
+  //   f2, s2
   // }
   // type s4 struct {
   // }
-  // func foo(x s1, y s2, z s4, sm1 uint8, sm2 int16, w s3) s2 {
+  // func foo(x s1, y s2, z s4, sm1 uint8, sm2 int8, w s3) s2 {
   //   if (sm1 == 0) {
   //     return y
   //   }
-  //   return foo(x, y, z, sm1-1, sm2, s3)
+  //   return foo(x, y, z, sm1-1, sm2, w)
   // }
   //
 
@@ -330,26 +347,26 @@
   Bstatement *rst2 = h.mkReturn(rvals2, FcnTestHarness::NoAppend);
 
   const char *exp = R"RAW_RESULT(
-  %p3.ld.0 = load i8, i8* %p3.addr
-  %sub.0 = sub i8 %p3.ld.0, 1
-  %p4.ld.0 = load i8, i8* %p4.addr
-  %cast.1 = bitcast { float, float, i16, i16, i16 }* %p0.addr to { <2 x float>, i48 }*
-  %field0.0 = getelementptr inbounds { <2 x float>, i48 }, { <2 x float>, i48 }* %cast.1, i32 0, i32 0
-  %ld.1 = load <2 x float>, <2 x float>* %field0.0
-  %field1.0 = getelementptr inbounds { <2 x float>, i48 }, { <2 x float>, i48 }* %cast.1, i32 0, i32 1
-  %ld.2 = load i48, i48* %field1.0
-  %cast.2 = bitcast { double, float, float }* %p1.addr to { double, <2 x float> }*
-  %field0.1 = getelementptr inbounds { double, <2 x float> }, { double, <2 x float> }* %cast.2, i32 0, i32 0
-  %ld.3 = load double, double* %field0.1
-  %field1.1 = getelementptr inbounds { double, <2 x float> }, { double, <2 x float> }* %cast.2, i32 0, i32 1
-  %ld.4 = load <2 x float>, <2 x float>* %field1.1
-  %call.0 = call addrspace(0) { double, <2 x float> } @foo(i8* nest undef, <2 x float> %ld.1, i48 %ld.2, double %ld.3, <2 x float> %ld.4, i8 zeroext %sub.0, i8 signext %p4.ld.0, { { float, float, i16, i16, i16 }, { double, float, float } }* byval %p5)
-  %cast.3 = bitcast { double, float, float }* %sret.actual.0 to { double, <2 x float> }*
-  store { double, <2 x float> } %call.0, { double, <2 x float> }* %cast.3
-  %cast.4 = bitcast { double, float, float }* %sret.actual.0 to { double, <2 x float> }*
-  %ld.5 = load { double, <2 x float> }, { double, <2 x float> }* %cast.4
-  ret { double, <2 x float> } %ld.5
-    )RAW_RESULT";
+    %p3.ld.0 = load i8, i8* %p3.addr
+    %sub.0 = sub i8 %p3.ld.0, 1
+    %p4.ld.0 = load i8, i8* %p4.addr
+    %cast.1 = bitcast { float, float, i16, i16, i16 }* %p0.addr to { <2 x float>, i48 }*
+    %field0.0 = getelementptr inbounds { <2 x float>, i48 }, { <2 x float>, i48 }* %cast.1, i32 0, i32 0
+    %ld.1 = load <2 x float>, <2 x float>* %field0.0
+    %field1.0 = getelementptr inbounds { <2 x float>, i48 }, { <2 x float>, i48 }* %cast.1, i32 0, i32 1
+    %ld.2 = load i48, i48* %field1.0
+    %cast.2 = bitcast { double, float, float }* %p1.addr to { double, <2 x float> }*
+    %field0.1 = getelementptr inbounds { double, <2 x float> }, { double, <2 x float> }* %cast.2, i32 0, i32 0
+    %ld.3 = load double, double* %field0.1
+    %field1.1 = getelementptr inbounds { double, <2 x float> }, { double, <2 x float> }* %cast.2, i32 0, i32 1
+    %ld.4 = load <2 x float>, <2 x float>* %field1.1
+    %call.0 = call addrspace(0) { double, <2 x float> } @foo(i8* nest undef, <2 x float> %ld.1, i48 %ld.2, double %ld.3, <2 x float> %ld.4, i8 zeroext %sub.0, i8 signext %p4.ld.0, { { float, float, i16, i16, i16 }, { double, float, float } }* byval %p5)
+    %cast.3 = bitcast { double, float, float }* %sret.actual.0 to { double, <2 x float> }*
+    store { double, <2 x float> } %call.0, { double, <2 x float> }* %cast.3
+    %cast.4 = bitcast { double, float, float }* %sret.actual.0 to { double, <2 x float> }*
+    %ld.5 = load { double, <2 x float> }, { double, <2 x float> }* %cast.4
+    ret { double, <2 x float> } %ld.5
+  )RAW_RESULT";
 
   bool isOK = h.expectStmt(rst2, exp);
   EXPECT_TRUE(isOK && "Statement does not have expected contents");
@@ -359,11 +376,10 @@
 
   bool broken = h.finish(PreserveDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
-
 }
 
-TEST(BackendCABIOracleTests, PassAndReturnArrays) {
-  FcnTestHarness h;
+TEST(BackendCABIOracleTests, PassAndReturnArraysAmd64) {
+  FcnTestHarness h(llvm::CallingConv::X86_64_SysV);
   Llvm_backend *be = h.be();
 
   Btype *bf32t = be->float_type(32);
@@ -400,7 +416,7 @@
     %cast.2 = bitcast [3 x double]* %sret.actual.0 to i8*
     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 %cast.2, i64 24, i1 false)
     ret void
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -409,8 +425,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendCABIOracleTests, EmptyStructParamsAndReturns) {
-  FcnTestHarness h;
+TEST_P(BackendCABIOracleTests, EmptyStructParamsAndReturns) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
 
   Btype *bi32t = be->integer_type(false, 32);
@@ -445,9 +462,9 @@
   h.mkReturn(rvals);
 
   const char *exp = R"RAW_RESULT(
-     call addrspace(0) void @foo(i8* nest undef, i32 4)
-     ret void
-    )RAW_RESULT";
+    call addrspace(0) void @foo(i8* nest undef, i32 4)
+    ret void
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -456,8 +473,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendCABIOracleTests, CallBuiltinFunction) {
-  FcnTestHarness h("foo");
+TEST_P(BackendCABIOracleTests, CallBuiltinFunction) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -470,8 +488,8 @@
   h.mkExprStmt(be->call_expression(func, fn, args, nullptr, h.loc()));
 
   const char *exp = R"RAW_RESULT(
-     call addrspace(0) void @llvm.trap()
-    )RAW_RESULT";
+    call addrspace(0) void @llvm.trap()
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -480,8 +498,8 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendCABIOracleTests, PassAndReturnComplex) {
-  FcnTestHarness h;
+TEST(BackendCABIOracleTests, PassAndReturnComplexAmd64) {
+  FcnTestHarness h(llvm::CallingConv::X86_64_SysV);
   Llvm_backend *be = h.be();
 
   Btype *bc64t = be->complex_type(64);
@@ -556,4 +574,4 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendCallTests.cpp b/unittests/BackendCore/BackendCallTests.cpp
index 82a3216..9ed5d93 100644
--- a/unittests/BackendCore/BackendCallTests.cpp
+++ b/unittests/BackendCore/BackendCallTests.cpp
@@ -17,9 +17,20 @@
 
 namespace {
 
-TEST(BackendCallTests, TestSimpleCall) {
+class BackendCallTests : public testing::TestWithParam<llvm::CallingConv::ID> {
+};
 
-  FcnTestHarness h("foo");
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendCallTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendCallTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendCallTests, TestSimpleCall) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -36,11 +47,11 @@
   h.mkReturn(be->var_expression(x, loc));
 
   const char *exp = R"RAW_RESULT(
-      %call.0 = call addrspace(0) i64 @foo(i8* nest undef, i32 3, i32 6, i64* null)
-      store i64 %call.0, i64* %x
-      %x.ld.0 = load i64, i64* %x
-      ret i64 %x.ld.0
-    )RAW_RESULT";
+    %call.0 = call addrspace(0) i64 @foo(i8* nest undef, i32 3, i32 6, i64* null)
+    store i64 %call.0, i64* %x
+    %x.ld.0 = load i64, i64* %x
+    ret i64 %x.ld.0
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -49,9 +60,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendCallTests, CallToVoid) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendCallTests, CallToVoid) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -69,8 +80,8 @@
   h.mkExprStmt(call);
 
   const char *exp = R"RAW_RESULT(
-     call addrspace(0) void @bar(i8* nest undef)
-    )RAW_RESULT";
+    call addrspace(0) void @bar(i8* nest undef)
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -79,9 +90,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendCallTests, MultiReturnCall) {
-
-  FcnTestHarness h;
+TEST_P(BackendCallTests, MultiReturnCall) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
 
   // Create function with multiple returns
@@ -108,10 +119,10 @@
 
   {
     const char *exp = R"RAW_RESULT(
-     %cast.0 = bitcast { i8*, i32*, i64*, i64 }* %sret.formal.0 to i8*
-     %cast.1 = bitcast { i8*, i32*, i64*, i64 }* @const.0 to i8*
-     call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 32, i1 false)
-     ret void
+      %cast.0 = bitcast { i8*, i32*, i64*, i64 }* %sret.formal.0 to i8*
+      %cast.1 = bitcast { i8*, i32*, i64*, i64 }* @const.0 to i8*
+      call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 32, i1 false)
+      ret void
     )RAW_RESULT";
 
     bool isOK = h.expectStmt(s1, exp);
@@ -133,19 +144,19 @@
 
   {
     const char *exp = R"RAW_RESULT(
-  %p0.ld.0 = load i8*, i8** %p0.addr
-  %field.0 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 0
-  store i8* %p0.ld.0, i8** %field.0
-  %field.1 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 1
-  store i32* null, i32** %field.1
-  %field.2 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 2
-  store i64* null, i64** %field.2
-  %field.3 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 3
-  store i64 101, i64* %field.3
-  %cast.3 = bitcast { i8*, i32*, i64*, i64 }* %sret.formal.0 to i8*
-  %cast.4 = bitcast { i8*, i32*, i64*, i64 }* %tmp.0 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.3, i8* align 8 %cast.4, i64 32, i1 false)
-  ret void
+      %p0.ld.0 = load i8*, i8** %p0.addr
+      %field.0 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 0
+      store i8* %p0.ld.0, i8** %field.0
+      %field.1 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 1
+      store i32* null, i32** %field.1
+      %field.2 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 2
+      store i64* null, i64** %field.2
+      %field.3 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 3
+      store i64 101, i64* %field.3
+      %cast.3 = bitcast { i8*, i32*, i64*, i64 }* %sret.formal.0 to i8*
+      %cast.4 = bitcast { i8*, i32*, i64*, i64 }* %tmp.0 to i8*
+      call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.3, i8* align 8 %cast.4, i64 32, i1 false)
+      ret void
     )RAW_RESULT";
 
     bool isOK = h.expectStmt(s2, exp);
@@ -163,9 +174,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendCallTests, CallToNoReturnFunction) {
-
-  FcnTestHarness h;
+TEST_P(BackendCallTests, CallToNoReturnFunction) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty);
@@ -210,7 +221,7 @@
     else.0:                                           ; preds = %entry
       br label %fallthrough.0
     }
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -219,4 +230,4 @@
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendCoreTests.cpp b/unittests/BackendCore/BackendCoreTests.cpp
index edbf1b6..7773a26 100644
--- a/unittests/BackendCore/BackendCoreTests.cpp
+++ b/unittests/BackendCore/BackendCoreTests.cpp
@@ -15,16 +15,27 @@
 
 namespace {
 
-TEST(BackendCoreTests, MakeBackend) {
-  LLVMContext C;
+class BackendCoreTests : public testing::TestWithParam<llvm::CallingConv::ID> {
+};
 
-  std::unique_ptr<Backend> makeit(go_get_backend(C));
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendCoreTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendCoreTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendCoreTests, MakeBackend) {
+  LLVMContext C;
+  auto cc = GetParam();
+  std::unique_ptr<Backend> makeit(go_get_backend(C, cc));
 }
 
-TEST(BackendCoreTests, ScalarTypes) {
+TEST_P(BackendCoreTests, ScalarTypes) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   Btype *et = be->error_type();
   EXPECT_TRUE(et != nullptr);
@@ -55,10 +66,10 @@
   }
 }
 
-TEST(BackendCoreTests, StructTypes) {
+TEST_P(BackendCoreTests, StructTypes) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   // Empty struct
   std::vector<Backend::Btyped_identifier> nofields;
@@ -91,10 +102,10 @@
   EXPECT_EQ(st1, st2);
 }
 
-TEST(BackendCoreTests, TypeHashAndCompare) {
+TEST_P(BackendCoreTests, TypeHashAndCompare) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   Btype *st1 = mkBackendThreeFieldStruct(be.get());
   Btype *st2 = mkBackendThreeFieldStruct(be.get());
@@ -102,13 +113,13 @@
   EXPECT_TRUE(st1->equal(*st1));
 }
 
-TEST(BackendCoreTests, ComplexTypes) {
+TEST_P(BackendCoreTests, ComplexTypes) {
   LLVMContext C;
 
   Type *ft = Type::getFloatTy(C);
   Type *dt = Type::getDoubleTy(C);
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
   Btype *c32 = be->complex_type(64);
   ASSERT_TRUE(c32 != nullptr);
   EXPECT_EQ(c32->type(), mkTwoFieldLLvmStruct(C, ft, ft));
@@ -117,12 +128,12 @@
   EXPECT_EQ(c64->type(), mkTwoFieldLLvmStruct(C, dt, dt));
 }
 
-TEST(BackendCoreTests, FunctionTypes) {
+TEST_P(BackendCoreTests, FunctionTypes) {
   LLVMContext C;
 
   Type *i64t = IntegerType::get(C, 64);
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   // func foo() {}
   Btype *emptyf = mkFuncTyp(be.get(), L_END);
@@ -133,8 +144,7 @@
   {
     // func (Blah) foo() {}
     Btype *pt = be->pointer_type(mkBackendThreeFieldStruct(be.get()));
-    Btype *befn =
-        mkFuncTyp(be.get(), L_RCV, pt, L_END);
+    Btype *befn = mkFuncTyp(be.get(), L_RCV, pt, L_END);
     llvm::PointerType *llpt =
         llvm::PointerType::get(mkLlvmThreeFieldStruct(C), 0);
     Type *llfn = mkLLFuncTyp(&C, L_RCV, llpt, L_END);
@@ -161,10 +171,10 @@
   }
 }
 
-TEST(BackendCoreTests, PlaceholderTypes) {
+TEST_P(BackendCoreTests, PlaceholderTypes) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   // Create a placeholder pointer type
   Location loc;
@@ -225,10 +235,10 @@
   EXPECT_EQ(php4->type(), cpt->type());
 }
 
-TEST(BackendCoreTests, ArrayTypes) {
+TEST_P(BackendCoreTests, ArrayTypes) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
   Location loc;
 
   // Very basic tests of array type creation: array of integers
@@ -260,10 +270,10 @@
   EXPECT_EQ(badt2, be->error_type());
 }
 
-TEST(BackendCoreTests, NamedTypes) {
+TEST_P(BackendCoreTests, NamedTypes) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
   Location loc;
   Btype *nt = be->named_type("named_int32", be->integer_type(false, 32), loc);
   ASSERT_TRUE(nt != nullptr);
@@ -274,12 +284,12 @@
   EXPECT_TRUE(nt->equivalent(*nt2));
 }
 
-TEST(BackendCoreTests, TypeUtils) {
+TEST_P(BackendCoreTests, TypeUtils) {
   LLVMContext C;
   Location loc;
-
+  auto cc = GetParam();
   // Type size and alignment. Size and align are in bytes.
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
   Btype *i8t = be->integer_type(false, 8);
   Btype *bs1f = mkBackendStruct(be.get(), i8t, "f1", nullptr);
   EXPECT_EQ(be->type_size(i8t), int64_t(1));
@@ -318,10 +328,10 @@
   EXPECT_EQ(be->type_field_alignment(u32), 4);
 }
 
-TEST(BackendCoreTests, TestTypeEquivalence) {
+TEST_P(BackendCoreTests, TestTypeEquivalence) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   // Two structs with same field type but different field names
   Btype *bi32t = be->integer_type(false, 32);
@@ -351,9 +361,9 @@
   EXPECT_TRUE(phst1->equivalent(*phst2));
 }
 
-TEST(BackendCoreTests, TestFcnPointerCompatible) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendCoreTests, TestFcnPointerCompatible) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   TypeManager *tm = be->typeManager();
   Location loc;
@@ -395,9 +405,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendCoreTests, TestCompositeInitGvarConvert) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendCoreTests, TestCompositeInitGvarConvert) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -459,9 +469,11 @@
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
 
-  bool ok = h.expectModuleDumpContains("@gv = global { { i8, i8*, i32 }, %ph.0 } { { i8, i8*, i32 } { i8 0, i8* null, i32 101 }, %ph.0 { i8 0, i8* null, i32 101 } }");
+  bool ok = h.expectModuleDumpContains(
+      "@gv = global { { i8, i8*, i32 }, %ph.0 } { { i8, i8*, i32 } { i8 0, "
+      "i8* "
+      "null, i32 101 }, %ph.0 { i8 0, i8* null, i32 101 } }");
   EXPECT_TRUE(ok);
-
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendDebugEmit.cpp b/unittests/BackendCore/BackendDebugEmit.cpp
index 327bc5f..03dfdd7 100644
--- a/unittests/BackendCore/BackendDebugEmit.cpp
+++ b/unittests/BackendCore/BackendDebugEmit.cpp
@@ -20,8 +20,20 @@
 // changed). Perhaps there is some other way to verify this
 // functionality.
 
-TEST(BackendDebugEmit, TestSimpleDecl) {
-  FcnTestHarness h;
+class BackendDebugEmit : public testing::TestWithParam<llvm::CallingConv::ID> {
+};
+
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendDebugEmit,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendDebugEmit::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendDebugEmit, TestSimpleDecl) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty);
@@ -30,14 +42,14 @@
   h.mkLocal("x", bu32t);
 
   const char *exp = R"RAW_RESULT(
-      define void @foo(i8* nest %nest.0) #0 {
-      entry:
-        %x = alloca i32
-        store i32 0, i32* %x
-        call void @llvm.dbg.declare(metadata i32* %x, metadata !5,
-                                    metadata !DIExpression()), !dbg !12
-        ret void
-      }
+    define void @foo(i8* nest %nest.0) #0 {
+    entry:
+      %x = alloca i32
+      store i32 0, i32* %x
+      call void @llvm.dbg.declare(metadata i32* %x, metadata !5,
+                                  metadata !DIExpression()), !dbg !12
+      ret void
+    }
   )RAW_RESULT";
 
   bool broken = h.finish(PreserveDebugInfo);
@@ -47,9 +59,9 @@
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-TEST(BackendDebugEmit, TestSimpleDecl2) {
+TEST(BackendDebugEmit, TestSimpleDecl2Amd64) {
   // Test that parameters of empty function are handled correctly.
-  FcnTestHarness h;
+  FcnTestHarness h(llvm::CallingConv::X86_64_SysV);
   Llvm_backend *be = h.be();
   Btype *bi64t = be->integer_type(false, 64);
   Btype *bst = mkBackendStruct(be, bi64t, "f1",
@@ -81,9 +93,9 @@
 // handles corner clases like vars with zero size (empty struct).
 
 // working propery
-TEST(BackendDebugEmit, MoreComplexVarDecls) {
-
-  FcnTestHarness h;
+TEST_P(BackendDebugEmit, MoreComplexVarDecls) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
 
   Btype *bi32t = be->integer_type(false, 32);
@@ -159,9 +171,10 @@
     std::cerr << fdump;
 }
 
-TEST(BackendDebugEmit, TestDeadLocalVar) {
+TEST_P(BackendDebugEmit, TestDeadLocalVar) {
+  auto cc = GetParam();
   // Test that dead local variable doesn't cause problem.
-  FcnTestHarness h;
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty);
@@ -185,8 +198,9 @@
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-TEST(BackendVarTests, TestGlobalVarDebugEmit) {
-  FcnTestHarness h("foo");
+TEST_P(BackendDebugEmit, TestGlobalVarDebugEmit) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc = h.loc();
 
@@ -207,12 +221,11 @@
   // wasn't skipped.
   bool ok = h.expectModuleDumpContains("!DIGlobalVariable(name: \"bar\",");
   EXPECT_TRUE(ok);
-
 }
 
-TEST(BackendDebugEmit, TestDebugPrefixMap) {
-
-  FcnTestHarness h;
+TEST_P(BackendDebugEmit, TestDebugPrefixMap) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   Btype *bi64t = be->integer_type(false, 64);
   BFunctionType *befty = mkFuncTyp(be, L_PARM, bi64t, L_RES, bi64t, L_END);
@@ -235,9 +248,9 @@
   EXPECT_TRUE(ok);
 }
 
-TEST(BackendDebugEmit, TestFileLineDirectives) {
-
-  FcnTestHarness h;
+TEST_P(BackendDebugEmit, TestFileLineDirectives) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   Btype *bi64t = be->integer_type(false, 64);
   BFunctionType *befty = mkFuncTyp(be, L_PARM, bi64t, L_RES, bi64t, L_END);
@@ -271,4 +284,4 @@
   EXPECT_TRUE(ok);
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendExprTests.cpp b/unittests/BackendCore/BackendExprTests.cpp
index 16e2f2f..b34ac85 100644
--- a/unittests/BackendCore/BackendExprTests.cpp
+++ b/unittests/BackendCore/BackendExprTests.cpp
@@ -17,10 +17,21 @@
 
 namespace {
 
-TEST(BackendExprTests, MakeBoolConstExpr) {
-  llvm::LLVMContext C;
+class BackendExprTests : public testing::TestWithParam<llvm::CallingConv::ID> {
+};
 
-  std::unique_ptr<Backend> be(go_get_backend(C));
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendExprTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendExprTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendExprTests, MakeBoolConstExpr) {
+  llvm::LLVMContext C;
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   // Boolean constants
   Bexpression *trueval = be->boolean_constant_expression(true);
@@ -31,10 +42,10 @@
   EXPECT_EQ(repr(falseval->value()), "i8 0");
 }
 
-TEST(BackendExprTests, MakeIntConstExpr) {
+TEST_P(BackendExprTests, MakeIntConstExpr) {
   llvm::LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   // Integer constants, signed and unsigned
   Btype *bi64t = be->integer_type(false, 64);
@@ -80,10 +91,10 @@
   mpz_clear(mpz_val);
 }
 
-TEST(BackendExprTests, MakeFloatConstExpr) {
+TEST_P(BackendExprTests, MakeFloatConstExpr) {
   llvm::LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   // Float constants
   Btype *bf32t = be->float_type(32);
@@ -132,10 +143,10 @@
   }
 }
 
-TEST(BackendExprTests, MakeComplexConstExpr) {
+TEST_P(BackendExprTests, MakeComplexConstExpr) {
   llvm::LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   // Complex constants
   Btype *bc64t = be->complex_type(64);
@@ -170,10 +181,10 @@
     }
 }
 
-TEST(BackendExprTests, MakeZeroValueExpr) {
+TEST_P(BackendExprTests, MakeZeroValueExpr) {
   llvm::LLVMContext C;
-
-  std::unique_ptr<Backend> bep(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> bep(go_get_backend(C, cc));
   Backend *be = bep.get();
 
   // Zero value expressions for various types
@@ -199,8 +210,9 @@
   EXPECT_EQ(be->zero_expression(be->error_type()), be->error_expression());
 }
 
-TEST(BackendExprTests, TestConversionExpressions) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestConversionExpressions) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -232,12 +244,12 @@
   h.mkAssign(fex, mkInt32Const(be, 22));
 
   const char *exp = R"RAW_RESULT(
-      store i64 0, i64* %x
-      %cast.0 = bitcast i64* %x to { i32, i32 }*
-      %field.0 = getelementptr inbounds { i32, i32 },
-          { i32, i32 }* %cast.0, i32 0, i32 1
-      store i32 22, i32* %field.0
-    )RAW_RESULT";
+    store i64 0, i64* %x
+    %cast.0 = bitcast i64* %x to { i32, i32 }*
+    %field.0 = getelementptr inbounds { i32, i32 },
+        { i32, i32 }* %cast.0, i32 0, i32 1
+    store i32 22, i32* %field.0
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -251,8 +263,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestMoreConversionExpressions) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestMoreConversionExpressions) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -283,15 +296,15 @@
   }
 
   const char *exp = R"RAW_RESULT(
-      %param3.ld.0 = load i64*, i64** %param3.addr
-      %cast.0 = bitcast i64* %param3.ld.0 to i32*
-      store i32 5, i32* %cast.0
-      store double 0.000000e+00, double* %p
-      %p.ld.0 = load double, double* %p
-      %ftoui.0 = fptoui double %p.ld.0 to i64
-      %itpcast.0 = inttoptr i64 %ftoui.0 to i32*
-      store i32 5, i32* %itpcast.0
-    )RAW_RESULT";
+    %param3.ld.0 = load i64*, i64** %param3.addr
+    %cast.0 = bitcast i64* %param3.ld.0 to i32*
+    store i32 5, i32* %cast.0
+    store double 0.000000e+00, double* %p
+    %p.ld.0 = load double, double* %p
+    %ftoui.0 = fptoui double %p.ld.0 to i64
+    %itpcast.0 = inttoptr i64 %ftoui.0 to i32*
+    store i32 5, i32* %itpcast.0
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -300,8 +313,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestFloatConversionExpressions) {
-  FcnTestHarness h;
+TEST_P(BackendExprTests, TestFloatConversionExpressions) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   Btype *bf32t = be->float_type(32);
   Btype *bf64t = be->float_type(64);
@@ -341,93 +355,93 @@
   }
 
   const char *exp = R"RAW_RESULT(
-  %p1.ld.0 = load double, double* %p1.addr
-  %fptrunc.0 = fptrunc double %p1.ld.0 to float
-  store float %fptrunc.0, float* %p0.addr
-  %p0.ld.0 = load float, float* %p0.addr
-  %fpext.0 = fpext float %p0.ld.0 to double
-  store double %fpext.0, double* %p1.addr
-  %p2.ld.0 = load i32, i32* %p2.addr
-  %sitof.0 = sitofp i32 %p2.ld.0 to float
-  store float %sitof.0, float* %p0.addr
-  %p0.ld.1 = load float, float* %p0.addr
-  %ftosi.0 = fptosi float %p0.ld.1 to i32
-  store i32 %ftosi.0, i32* %p2.addr
-  %p2.ld.1 = load i32, i32* %p2.addr
-  %sitof.1 = sitofp i32 %p2.ld.1 to double
-  store double %sitof.1, double* %p1.addr
-  %p1.ld.1 = load double, double* %p1.addr
-  %ftosi.1 = fptosi double %p1.ld.1 to i32
-  store i32 %ftosi.1, i32* %p2.addr
-  %p3.ld.0 = load i64, i64* %p3.addr
-  %sitof.2 = sitofp i64 %p3.ld.0 to float
-  store float %sitof.2, float* %p0.addr
-  %p0.ld.2 = load float, float* %p0.addr
-  %ftosi.2 = fptosi float %p0.ld.2 to i64
-  store i64 %ftosi.2, i64* %p3.addr
-  %p3.ld.1 = load i64, i64* %p3.addr
-  %sitof.3 = sitofp i64 %p3.ld.1 to double
-  store double %sitof.3, double* %p1.addr
-  %p1.ld.2 = load double, double* %p1.addr
-  %ftosi.3 = fptosi double %p1.ld.2 to i64
-  store i64 %ftosi.3, i64* %p3.addr
-  %p3.ld.2 = load i64, i64* %p3.addr
-  %trunc.0 = trunc i64 %p3.ld.2 to i32
-  store i32 %trunc.0, i32* %p2.addr
-  %p2.ld.2 = load i32, i32* %p2.addr
-  %sext.0 = sext i32 %p2.ld.2 to i64
-  store i64 %sext.0, i64* %p3.addr
-  %p4.ld.0 = load i32, i32* %p4.addr
-  %uitof.0 = uitofp i32 %p4.ld.0 to float
-  store float %uitof.0, float* %p0.addr
-  %p0.ld.3 = load float, float* %p0.addr
-  %ftoui.0 = fptoui float %p0.ld.3 to i32
-  store i32 %ftoui.0, i32* %p4.addr
-  %p4.ld.1 = load i32, i32* %p4.addr
-  %uitof.1 = uitofp i32 %p4.ld.1 to double
-  store double %uitof.1, double* %p1.addr
-  %p1.ld.3 = load double, double* %p1.addr
-  %ftoui.1 = fptoui double %p1.ld.3 to i32
-  store i32 %ftoui.1, i32* %p4.addr
-  %p4.ld.2 = load i32, i32* %p4.addr
-  store i32 %p4.ld.2, i32* %p2.addr
-  %p2.ld.3 = load i32, i32* %p2.addr
-  store i32 %p2.ld.3, i32* %p4.addr
-  %p4.ld.3 = load i32, i32* %p4.addr
-  %zext.0 = zext i32 %p4.ld.3 to i64
-  store i64 %zext.0, i64* %p3.addr
-  %p3.ld.3 = load i64, i64* %p3.addr
-  %trunc.1 = trunc i64 %p3.ld.3 to i32
-  store i32 %trunc.1, i32* %p4.addr
-  %p5.ld.0 = load i64, i64* %p5.addr
-  %uitof.2 = uitofp i64 %p5.ld.0 to float
-  store float %uitof.2, float* %p0.addr
-  %p0.ld.4 = load float, float* %p0.addr
-  %ftoui.2 = fptoui float %p0.ld.4 to i64
-  store i64 %ftoui.2, i64* %p5.addr
-  %p5.ld.1 = load i64, i64* %p5.addr
-  %uitof.3 = uitofp i64 %p5.ld.1 to double
-  store double %uitof.3, double* %p1.addr
-  %p1.ld.4 = load double, double* %p1.addr
-  %ftoui.3 = fptoui double %p1.ld.4 to i64
-  store i64 %ftoui.3, i64* %p5.addr
-  %p5.ld.2 = load i64, i64* %p5.addr
-  %trunc.2 = trunc i64 %p5.ld.2 to i32
-  store i32 %trunc.2, i32* %p2.addr
-  %p2.ld.4 = load i32, i32* %p2.addr
-  %sext.1 = sext i32 %p2.ld.4 to i64
-  store i64 %sext.1, i64* %p5.addr
-  %p5.ld.3 = load i64, i64* %p5.addr
-  store i64 %p5.ld.3, i64* %p3.addr
-  %p3.ld.4 = load i64, i64* %p3.addr
-  store i64 %p3.ld.4, i64* %p5.addr
-  %p5.ld.4 = load i64, i64* %p5.addr
-  %trunc.3 = trunc i64 %p5.ld.4 to i32
-  store i32 %trunc.3, i32* %p4.addr
-  %p4.ld.4 = load i32, i32* %p4.addr
-  %zext.1 = zext i32 %p4.ld.4 to i64
-  store i64 %zext.1, i64* %p5.addr
-    )RAW_RESULT";
+    %p1.ld.0 = load double, double* %p1.addr
+    %fptrunc.0 = fptrunc double %p1.ld.0 to float
+    store float %fptrunc.0, float* %p0.addr
+    %p0.ld.0 = load float, float* %p0.addr
+    %fpext.0 = fpext float %p0.ld.0 to double
+    store double %fpext.0, double* %p1.addr
+    %p2.ld.0 = load i32, i32* %p2.addr
+    %sitof.0 = sitofp i32 %p2.ld.0 to float
+    store float %sitof.0, float* %p0.addr
+    %p0.ld.1 = load float, float* %p0.addr
+    %ftosi.0 = fptosi float %p0.ld.1 to i32
+    store i32 %ftosi.0, i32* %p2.addr
+    %p2.ld.1 = load i32, i32* %p2.addr
+    %sitof.1 = sitofp i32 %p2.ld.1 to double
+    store double %sitof.1, double* %p1.addr
+    %p1.ld.1 = load double, double* %p1.addr
+    %ftosi.1 = fptosi double %p1.ld.1 to i32
+    store i32 %ftosi.1, i32* %p2.addr
+    %p3.ld.0 = load i64, i64* %p3.addr
+    %sitof.2 = sitofp i64 %p3.ld.0 to float
+    store float %sitof.2, float* %p0.addr
+    %p0.ld.2 = load float, float* %p0.addr
+    %ftosi.2 = fptosi float %p0.ld.2 to i64
+    store i64 %ftosi.2, i64* %p3.addr
+    %p3.ld.1 = load i64, i64* %p3.addr
+    %sitof.3 = sitofp i64 %p3.ld.1 to double
+    store double %sitof.3, double* %p1.addr
+    %p1.ld.2 = load double, double* %p1.addr
+    %ftosi.3 = fptosi double %p1.ld.2 to i64
+    store i64 %ftosi.3, i64* %p3.addr
+    %p3.ld.2 = load i64, i64* %p3.addr
+    %trunc.0 = trunc i64 %p3.ld.2 to i32
+    store i32 %trunc.0, i32* %p2.addr
+    %p2.ld.2 = load i32, i32* %p2.addr
+    %sext.0 = sext i32 %p2.ld.2 to i64
+    store i64 %sext.0, i64* %p3.addr
+    %p4.ld.0 = load i32, i32* %p4.addr
+    %uitof.0 = uitofp i32 %p4.ld.0 to float
+    store float %uitof.0, float* %p0.addr
+    %p0.ld.3 = load float, float* %p0.addr
+    %ftoui.0 = fptoui float %p0.ld.3 to i32
+    store i32 %ftoui.0, i32* %p4.addr
+    %p4.ld.1 = load i32, i32* %p4.addr
+    %uitof.1 = uitofp i32 %p4.ld.1 to double
+    store double %uitof.1, double* %p1.addr
+    %p1.ld.3 = load double, double* %p1.addr
+    %ftoui.1 = fptoui double %p1.ld.3 to i32
+    store i32 %ftoui.1, i32* %p4.addr
+    %p4.ld.2 = load i32, i32* %p4.addr
+    store i32 %p4.ld.2, i32* %p2.addr
+    %p2.ld.3 = load i32, i32* %p2.addr
+    store i32 %p2.ld.3, i32* %p4.addr
+    %p4.ld.3 = load i32, i32* %p4.addr
+    %zext.0 = zext i32 %p4.ld.3 to i64
+    store i64 %zext.0, i64* %p3.addr
+    %p3.ld.3 = load i64, i64* %p3.addr
+    %trunc.1 = trunc i64 %p3.ld.3 to i32
+    store i32 %trunc.1, i32* %p4.addr
+    %p5.ld.0 = load i64, i64* %p5.addr
+    %uitof.2 = uitofp i64 %p5.ld.0 to float
+    store float %uitof.2, float* %p0.addr
+    %p0.ld.4 = load float, float* %p0.addr
+    %ftoui.2 = fptoui float %p0.ld.4 to i64
+    store i64 %ftoui.2, i64* %p5.addr
+    %p5.ld.1 = load i64, i64* %p5.addr
+    %uitof.3 = uitofp i64 %p5.ld.1 to double
+    store double %uitof.3, double* %p1.addr
+    %p1.ld.4 = load double, double* %p1.addr
+    %ftoui.3 = fptoui double %p1.ld.4 to i64
+    store i64 %ftoui.3, i64* %p5.addr
+    %p5.ld.2 = load i64, i64* %p5.addr
+    %trunc.2 = trunc i64 %p5.ld.2 to i32
+    store i32 %trunc.2, i32* %p2.addr
+    %p2.ld.4 = load i32, i32* %p2.addr
+    %sext.1 = sext i32 %p2.ld.4 to i64
+    store i64 %sext.1, i64* %p5.addr
+    %p5.ld.3 = load i64, i64* %p5.addr
+    store i64 %p5.ld.3, i64* %p3.addr
+    %p3.ld.4 = load i64, i64* %p3.addr
+    store i64 %p3.ld.4, i64* %p5.addr
+    %p5.ld.4 = load i64, i64* %p5.addr
+    %trunc.3 = trunc i64 %p5.ld.4 to i32
+    store i32 %trunc.3, i32* %p4.addr
+    %p4.ld.4 = load i32, i32* %p4.addr
+    %zext.1 = zext i32 %p4.ld.4 to i64
+    store i64 %zext.1, i64* %p5.addr
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -436,8 +450,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestComplexConversionExpression) {
-  FcnTestHarness h;
+TEST_P(BackendExprTests, TestComplexConversionExpression) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty);
@@ -479,68 +494,68 @@
   h.mkAssign(xvex4, convex4);
 
   const char *exp = R"RAW_RESULT(
-define void @foo(i8* nest %nest.0) #0 {
-entry:
-  %tmp.3 = alloca { double, double }
-  %tmp.2 = alloca { float, float }
-  %tmp.1 = alloca { float, float }
-  %tmp.0 = alloca { double, double }
-  %a = alloca { float, float }
-  %b = alloca { float, float }
-  %x = alloca { double, double }
-  %y = alloca { double, double }
-  %cast.0 = bitcast { float, float }* %a to i8*
-  %cast.1 = bitcast { float, float }* @const.0 to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 %cast.1, i64 8, i1 false)
-  %cast.2 = bitcast { float, float }* %b to i8*
-  %cast.3 = bitcast { float, float }* @const.0 to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 %cast.3, i64 8, i1 false)
-  %cast.4 = bitcast { double, double }* %x to i8*
-  %cast.5 = bitcast { double, double }* @const.1 to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.4, i8* align 8 %cast.5, i64 16, i1 false)
-  %cast.6 = bitcast { double, double }* %y to i8*
-  %cast.7 = bitcast { double, double }* @const.1 to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.6, i8* align 8 %cast.7, i64 16, i1 false)
-  %cast.8 = bitcast { double, double }* %tmp.0 to i8*
-  %cast.9 = bitcast { double, double }* %x to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.8, i8* align 8 %cast.9, i64 16, i1 false)
-  %field.0 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 0
-  %.real.ld.0 = load double, double* %field.0
-  %fptrunc.0 = fptrunc double %.real.ld.0 to float
-  %field.1 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 1
-  %.imag.ld.0 = load double, double* %field.1
-  %fptrunc.1 = fptrunc double %.imag.ld.0 to float
-  %field.2 = getelementptr inbounds { float, float }, { float, float }* %tmp.1, i32 0, i32 0
-  store float %fptrunc.0, float* %field.2
-  %field.3 = getelementptr inbounds { float, float }, { float, float }* %tmp.1, i32 0, i32 1
-  store float %fptrunc.1, float* %field.3
-  %cast.10 = bitcast { float, float }* %a to i8*
-  %cast.11 = bitcast { float, float }* %tmp.1 to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.10, i8* align 4 %cast.11, i64 8, i1 false)
-  %cast.12 = bitcast { float, float }* %tmp.2 to i8*
-  %cast.13 = bitcast { float, float }* %b to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.12, i8* align 4 %cast.13, i64 8, i1 false)
-  %field.4 = getelementptr inbounds { float, float }, { float, float }* %tmp.2, i32 0, i32 0
-  %.real.ld.1 = load float, float* %field.4
-  %fpext.0 = fpext float %.real.ld.1 to double
-  %field.5 = getelementptr inbounds { float, float }, { float, float }* %tmp.2, i32 0, i32 1
-  %.imag.ld.1 = load float, float* %field.5
-  %fpext.1 = fpext float %.imag.ld.1 to double
-  %field.6 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 0
-  store double %fpext.0, double* %field.6
-  %field.7 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 1
-  store double %fpext.1, double* %field.7
-  %cast.14 = bitcast { double, double }* %y to i8*
-  %cast.15 = bitcast { double, double }* %tmp.3 to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.14, i8* align 8 %cast.15, i64 16, i1 false)
-  %cast.16 = bitcast { float, float }* %a to i8*
-  %cast.17 = bitcast { float, float }* %b to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.16, i8* align 4 %cast.17, i64 8, i1 false)
-  %cast.18 = bitcast { double, double }* %x to i8*
-  %cast.19 = bitcast { double, double }* %y to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.18, i8* align 8 %cast.19, i64 16, i1 false)
-  ret void
-}
+    define void @foo(i8* nest %nest.0) #0 {
+    entry:
+      %tmp.3 = alloca { double, double }
+      %tmp.2 = alloca { float, float }
+      %tmp.1 = alloca { float, float }
+      %tmp.0 = alloca { double, double }
+      %a = alloca { float, float }
+      %b = alloca { float, float }
+      %x = alloca { double, double }
+      %y = alloca { double, double }
+      %cast.0 = bitcast { float, float }* %a to i8*
+      %cast.1 = bitcast { float, float }* @const.0 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 %cast.1, i64 8, i1 false)
+      %cast.2 = bitcast { float, float }* %b to i8*
+      %cast.3 = bitcast { float, float }* @const.0 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 %cast.3, i64 8, i1 false)
+      %cast.4 = bitcast { double, double }* %x to i8*
+      %cast.5 = bitcast { double, double }* @const.1 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.4, i8* align 8 %cast.5, i64 16, i1 false)
+      %cast.6 = bitcast { double, double }* %y to i8*
+      %cast.7 = bitcast { double, double }* @const.1 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.6, i8* align 8 %cast.7, i64 16, i1 false)
+      %cast.8 = bitcast { double, double }* %tmp.0 to i8*
+      %cast.9 = bitcast { double, double }* %x to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.8, i8* align 8 %cast.9, i64 16, i1 false)
+      %field.0 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 0
+      %.real.ld.0 = load double, double* %field.0
+      %fptrunc.0 = fptrunc double %.real.ld.0 to float
+      %field.1 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 1
+      %.imag.ld.0 = load double, double* %field.1
+      %fptrunc.1 = fptrunc double %.imag.ld.0 to float
+      %field.2 = getelementptr inbounds { float, float }, { float, float }* %tmp.1, i32 0, i32 0
+      store float %fptrunc.0, float* %field.2
+      %field.3 = getelementptr inbounds { float, float }, { float, float }* %tmp.1, i32 0, i32 1
+      store float %fptrunc.1, float* %field.3
+      %cast.10 = bitcast { float, float }* %a to i8*
+      %cast.11 = bitcast { float, float }* %tmp.1 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.10, i8* align 4 %cast.11, i64 8, i1 false)
+      %cast.12 = bitcast { float, float }* %tmp.2 to i8*
+      %cast.13 = bitcast { float, float }* %b to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.12, i8* align 4 %cast.13, i64 8, i1 false)
+      %field.4 = getelementptr inbounds { float, float }, { float, float }* %tmp.2, i32 0, i32 0
+      %.real.ld.1 = load float, float* %field.4
+      %fpext.0 = fpext float %.real.ld.1 to double
+      %field.5 = getelementptr inbounds { float, float }, { float, float }* %tmp.2, i32 0, i32 1
+      %.imag.ld.1 = load float, float* %field.5
+      %fpext.1 = fpext float %.imag.ld.1 to double
+      %field.6 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 0
+      store double %fpext.0, double* %field.6
+      %field.7 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 1
+      store double %fpext.1, double* %field.7
+      %cast.14 = bitcast { double, double }* %y to i8*
+      %cast.15 = bitcast { double, double }* %tmp.3 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.14, i8* align 8 %cast.15, i64 16, i1 false)
+      %cast.16 = bitcast { float, float }* %a to i8*
+      %cast.17 = bitcast { float, float }* %b to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.16, i8* align 4 %cast.17, i64 8, i1 false)
+      %cast.18 = bitcast { double, double }* %x to i8*
+      %cast.19 = bitcast { double, double }* %y to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.18, i8* align 8 %cast.19, i64 16, i1 false)
+      ret void
+    }
   )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
@@ -550,8 +565,9 @@
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-TEST(BackendExprTests, MakeVarExpressions) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, MakeVarExpressions) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -583,8 +599,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestCompareOps) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestCompareOps) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -618,64 +635,64 @@
   }
 
   const char *exp = R"RAW_RESULT(
-      store i64 0, i64* %x
-      store i64 0, i64* %y
-      store double 0.000000e+00, double* %z
-      %x.ld.0 = load i64, i64* %x
-      %icmp.0 = icmp eq i64 9, %x.ld.0
-      %zext.0 = zext i1 %icmp.0 to i8
-      %x.ld.1 = load i64, i64* %x
-      %icmp.1 = icmp ne i64 9, %x.ld.1
-      %zext.1 = zext i1 %icmp.1 to i8
-      %x.ld.2 = load i64, i64* %x
-      %icmp.2 = icmp slt i64 9, %x.ld.2
-      %zext.2 = zext i1 %icmp.2 to i8
-      %x.ld.3 = load i64, i64* %x
-      %icmp.3 = icmp sle i64 9, %x.ld.3
-      %zext.3 = zext i1 %icmp.3 to i8
-      %x.ld.4 = load i64, i64* %x
-      %icmp.4 = icmp sgt i64 9, %x.ld.4
-      %zext.4 = zext i1 %icmp.4 to i8
-      %x.ld.5 = load i64, i64* %x
-      %icmp.5 = icmp sge i64 9, %x.ld.5
-      %zext.5 = zext i1 %icmp.5 to i8
-      %y.ld.0 = load i64, i64* %y
-      %icmp.6 = icmp eq i64 9, %y.ld.0
-      %zext.6 = zext i1 %icmp.6 to i8
-      %y.ld.1 = load i64, i64* %y
-      %icmp.7 = icmp ne i64 9, %y.ld.1
-      %zext.7 = zext i1 %icmp.7 to i8
-      %y.ld.2 = load i64, i64* %y
-      %icmp.8 = icmp ult i64 9, %y.ld.2
-      %zext.8 = zext i1 %icmp.8 to i8
-      %y.ld.3 = load i64, i64* %y
-      %icmp.9 = icmp ule i64 9, %y.ld.3
-      %zext.9 = zext i1 %icmp.9 to i8
-      %y.ld.4 = load i64, i64* %y
-      %icmp.10 = icmp ugt i64 9, %y.ld.4
-      %zext.10 = zext i1 %icmp.10 to i8
-      %y.ld.5 = load i64, i64* %y
-      %icmp.11 = icmp uge i64 9, %y.ld.5
-      %zext.11 = zext i1 %icmp.11 to i8
-      %z.ld.0 = load double, double* %z
-      %fcmp.0 = fcmp oeq double 9.000000e+00, %z.ld.0
-      %zext.12 = zext i1 %fcmp.0 to i8
-      %z.ld.1 = load double, double* %z
-      %fcmp.1 = fcmp une double 9.000000e+00, %z.ld.1
-      %zext.13 = zext i1 %fcmp.1 to i8
-      %z.ld.2 = load double, double* %z
-      %fcmp.2 = fcmp olt double 9.000000e+00, %z.ld.2
-      %zext.14 = zext i1 %fcmp.2 to i8
-      %z.ld.3 = load double, double* %z
-      %fcmp.3 = fcmp ole double 9.000000e+00, %z.ld.3
-      %zext.15 = zext i1 %fcmp.3 to i8
-      %z.ld.4 = load double, double* %z
-      %fcmp.4 = fcmp ogt double 9.000000e+00, %z.ld.4
-      %zext.16 = zext i1 %fcmp.4 to i8
-      %z.ld.5 = load double, double* %z
-      %fcmp.5 = fcmp oge double 9.000000e+00, %z.ld.5
-      %zext.17 = zext i1 %fcmp.5 to i8
-    )RAW_RESULT";
+    store i64 0, i64* %x
+    store i64 0, i64* %y
+    store double 0.000000e+00, double* %z
+    %x.ld.0 = load i64, i64* %x
+    %icmp.0 = icmp eq i64 9, %x.ld.0
+    %zext.0 = zext i1 %icmp.0 to i8
+    %x.ld.1 = load i64, i64* %x
+    %icmp.1 = icmp ne i64 9, %x.ld.1
+    %zext.1 = zext i1 %icmp.1 to i8
+    %x.ld.2 = load i64, i64* %x
+    %icmp.2 = icmp slt i64 9, %x.ld.2
+    %zext.2 = zext i1 %icmp.2 to i8
+    %x.ld.3 = load i64, i64* %x
+    %icmp.3 = icmp sle i64 9, %x.ld.3
+    %zext.3 = zext i1 %icmp.3 to i8
+    %x.ld.4 = load i64, i64* %x
+    %icmp.4 = icmp sgt i64 9, %x.ld.4
+    %zext.4 = zext i1 %icmp.4 to i8
+    %x.ld.5 = load i64, i64* %x
+    %icmp.5 = icmp sge i64 9, %x.ld.5
+    %zext.5 = zext i1 %icmp.5 to i8
+    %y.ld.0 = load i64, i64* %y
+    %icmp.6 = icmp eq i64 9, %y.ld.0
+    %zext.6 = zext i1 %icmp.6 to i8
+    %y.ld.1 = load i64, i64* %y
+    %icmp.7 = icmp ne i64 9, %y.ld.1
+    %zext.7 = zext i1 %icmp.7 to i8
+    %y.ld.2 = load i64, i64* %y
+    %icmp.8 = icmp ult i64 9, %y.ld.2
+    %zext.8 = zext i1 %icmp.8 to i8
+    %y.ld.3 = load i64, i64* %y
+    %icmp.9 = icmp ule i64 9, %y.ld.3
+    %zext.9 = zext i1 %icmp.9 to i8
+    %y.ld.4 = load i64, i64* %y
+    %icmp.10 = icmp ugt i64 9, %y.ld.4
+    %zext.10 = zext i1 %icmp.10 to i8
+    %y.ld.5 = load i64, i64* %y
+    %icmp.11 = icmp uge i64 9, %y.ld.5
+    %zext.11 = zext i1 %icmp.11 to i8
+    %z.ld.0 = load double, double* %z
+    %fcmp.0 = fcmp oeq double 9.000000e+00, %z.ld.0
+    %zext.12 = zext i1 %fcmp.0 to i8
+    %z.ld.1 = load double, double* %z
+    %fcmp.1 = fcmp une double 9.000000e+00, %z.ld.1
+    %zext.13 = zext i1 %fcmp.1 to i8
+    %z.ld.2 = load double, double* %z
+    %fcmp.2 = fcmp olt double 9.000000e+00, %z.ld.2
+    %zext.14 = zext i1 %fcmp.2 to i8
+    %z.ld.3 = load double, double* %z
+    %fcmp.3 = fcmp ole double 9.000000e+00, %z.ld.3
+    %zext.15 = zext i1 %fcmp.3 to i8
+    %z.ld.4 = load double, double* %z
+    %fcmp.4 = fcmp ogt double 9.000000e+00, %z.ld.4
+    %zext.16 = zext i1 %fcmp.4 to i8
+    %z.ld.5 = load double, double* %z
+    %fcmp.5 = fcmp oge double 9.000000e+00, %z.ld.5
+    %zext.17 = zext i1 %fcmp.5 to i8
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -684,8 +701,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestArithOps) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestArithOps) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -714,16 +732,16 @@
   }
 
   const char *exp = R"RAW_RESULT(
-      store i64 0, i64* %x
-      store double 0.000000e+00, double* %y
-      %x.ld.0 = load i64, i64* %x
-      %add.0 = add i64 9, %x.ld.0
-      %x.ld.1 = load i64, i64* %x
-      %sub.0 = sub i64 9, %x.ld.1
-      %y.ld.0 = load double, double* %y
-      %fadd.0 = fadd double 9.000000e+00, %y.ld.0
-      %y.ld.1 = load double, double* %y
-      %fsub.0 = fsub double 9.000000e+00, %y.ld.1
+    store i64 0, i64* %x
+    store double 0.000000e+00, double* %y
+    %x.ld.0 = load i64, i64* %x
+    %add.0 = add i64 9, %x.ld.0
+    %x.ld.1 = load i64, i64* %x
+    %sub.0 = sub i64 9, %x.ld.1
+    %y.ld.0 = load double, double* %y
+    %fadd.0 = fadd double 9.000000e+00, %y.ld.0
+    %y.ld.1 = load double, double* %y
+    %fsub.0 = fsub double 9.000000e+00, %y.ld.1
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -733,8 +751,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestMoreArith) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestMoreArith) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   // var x int64, y = 9, z = 10, w = 11
@@ -755,16 +774,16 @@
   h.mkAssign(vex, ypzpw);
 
   const char *exp = R"RAW_RESULT(
-  store i64 0, i64* %x
-  store i64 9, i64* %y
-  store i64 10, i64* %z
-  store i64 11, i64* %w
-  %y.ld.0 = load i64, i64* %y
-  %z.ld.0 = load i64, i64* %z
-  %add.0 = add i64 %y.ld.0, %z.ld.0
-  %w.ld.0 = load i64, i64* %w
-  %add.1 = add i64 %add.0, %w.ld.0
-  store i64 %add.1, i64* %x
+    store i64 0, i64* %x
+    store i64 9, i64* %y
+    store i64 10, i64* %z
+    store i64 11, i64* %w
+    %y.ld.0 = load i64, i64* %y
+    %z.ld.0 = load i64, i64* %z
+    %add.0 = add i64 %y.ld.0, %z.ld.0
+    %w.ld.0 = load i64, i64* %w
+    %add.1 = add i64 %add.0, %w.ld.0
+    store i64 %add.1, i64* %x
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -774,8 +793,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestLogicalOps) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestLogicalOps) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -810,67 +830,67 @@
   }
 
   const char *exp = R"RAW_RESULT(
-      store i64 0, i64* %x
-      store i64 0, i64* %y
-      store i8 0, i8* %z
-      store i64 0, i64* %x2
-      store i64 0, i64* %y2
-      store i8 0, i8* %z2
-      %x.ld.0 = load i64, i64* %x
-      %x2.ld.0 = load i64, i64* %x2
-      %iand.0 = and i64 %x.ld.0, %x2.ld.0
-      %x.ld.1 = load i64, i64* %x
-      %x2.ld.1 = load i64, i64* %x2
-      %ior.0 = or i64 %x.ld.1, %x2.ld.1
-      %x.ld.2 = load i64, i64* %x
-      %x2.ld.2 = load i64, i64* %x2
-      %iand.1 = and i64 %x.ld.2, %x2.ld.2
-      %x.ld.3 = load i64, i64* %x
-      %x2.ld.3 = load i64, i64* %x2
-      %ior.1 = or i64 %x.ld.3, %x2.ld.3
-      %x.ld.4 = load i64, i64* %x
-      %x2.ld.4 = load i64, i64* %x2
-      %xor.0 = xor i64 %x.ld.4, %x2.ld.4
-      %x.ld.5 = load i64, i64* %x
-      %x2.ld.5 = load i64, i64* %x2
-      %iand.2 = and i64 %x.ld.5, %x2.ld.5
-      %y.ld.0 = load i64, i64* %y
-      %y2.ld.0 = load i64, i64* %y2
-      %iand.3 = and i64 %y.ld.0, %y2.ld.0
-      %y.ld.1 = load i64, i64* %y
-      %y2.ld.1 = load i64, i64* %y2
-      %ior.2 = or i64 %y.ld.1, %y2.ld.1
-      %y.ld.2 = load i64, i64* %y
-      %y2.ld.2 = load i64, i64* %y2
-      %iand.4 = and i64 %y.ld.2, %y2.ld.2
-      %y.ld.3 = load i64, i64* %y
-      %y2.ld.3 = load i64, i64* %y2
-      %ior.3 = or i64 %y.ld.3, %y2.ld.3
-      %y.ld.4 = load i64, i64* %y
-      %y2.ld.4 = load i64, i64* %y2
-      %xor.1 = xor i64 %y.ld.4, %y2.ld.4
-      %y.ld.5 = load i64, i64* %y
-      %y2.ld.5 = load i64, i64* %y2
-      %iand.5 = and i64 %y.ld.5, %y2.ld.5
-      %z.ld.0 = load i8, i8* %z
-      %z2.ld.0 = load i8, i8* %z2
-      %iand.6 = and i8 %z.ld.0, %z2.ld.0
-      %z.ld.1 = load i8, i8* %z
-      %z2.ld.1 = load i8, i8* %z2
-      %ior.4 = or i8 %z.ld.1, %z2.ld.1
-      %z.ld.2 = load i8, i8* %z
-      %z2.ld.2 = load i8, i8* %z2
-      %iand.7 = and i8 %z.ld.2, %z2.ld.2
-      %z.ld.3 = load i8, i8* %z
-      %z2.ld.3 = load i8, i8* %z2
-      %ior.5 = or i8 %z.ld.3, %z2.ld.3
-      %z.ld.4 = load i8, i8* %z
-      %z2.ld.4 = load i8, i8* %z2
-      %xor.2 = xor i8 %z.ld.4, %z2.ld.4
-      %z.ld.5 = load i8, i8* %z
-      %z2.ld.5 = load i8, i8* %z2
-      %iand.8 = and i8 %z.ld.5, %z2.ld.5
-    )RAW_RESULT";
+    store i64 0, i64* %x
+    store i64 0, i64* %y
+    store i8 0, i8* %z
+    store i64 0, i64* %x2
+    store i64 0, i64* %y2
+    store i8 0, i8* %z2
+    %x.ld.0 = load i64, i64* %x
+    %x2.ld.0 = load i64, i64* %x2
+    %iand.0 = and i64 %x.ld.0, %x2.ld.0
+    %x.ld.1 = load i64, i64* %x
+    %x2.ld.1 = load i64, i64* %x2
+    %ior.0 = or i64 %x.ld.1, %x2.ld.1
+    %x.ld.2 = load i64, i64* %x
+    %x2.ld.2 = load i64, i64* %x2
+    %iand.1 = and i64 %x.ld.2, %x2.ld.2
+    %x.ld.3 = load i64, i64* %x
+    %x2.ld.3 = load i64, i64* %x2
+    %ior.1 = or i64 %x.ld.3, %x2.ld.3
+    %x.ld.4 = load i64, i64* %x
+    %x2.ld.4 = load i64, i64* %x2
+    %xor.0 = xor i64 %x.ld.4, %x2.ld.4
+    %x.ld.5 = load i64, i64* %x
+    %x2.ld.5 = load i64, i64* %x2
+    %iand.2 = and i64 %x.ld.5, %x2.ld.5
+    %y.ld.0 = load i64, i64* %y
+    %y2.ld.0 = load i64, i64* %y2
+    %iand.3 = and i64 %y.ld.0, %y2.ld.0
+    %y.ld.1 = load i64, i64* %y
+    %y2.ld.1 = load i64, i64* %y2
+    %ior.2 = or i64 %y.ld.1, %y2.ld.1
+    %y.ld.2 = load i64, i64* %y
+    %y2.ld.2 = load i64, i64* %y2
+    %iand.4 = and i64 %y.ld.2, %y2.ld.2
+    %y.ld.3 = load i64, i64* %y
+    %y2.ld.3 = load i64, i64* %y2
+    %ior.3 = or i64 %y.ld.3, %y2.ld.3
+    %y.ld.4 = load i64, i64* %y
+    %y2.ld.4 = load i64, i64* %y2
+    %xor.1 = xor i64 %y.ld.4, %y2.ld.4
+    %y.ld.5 = load i64, i64* %y
+    %y2.ld.5 = load i64, i64* %y2
+    %iand.5 = and i64 %y.ld.5, %y2.ld.5
+    %z.ld.0 = load i8, i8* %z
+    %z2.ld.0 = load i8, i8* %z2
+    %iand.6 = and i8 %z.ld.0, %z2.ld.0
+    %z.ld.1 = load i8, i8* %z
+    %z2.ld.1 = load i8, i8* %z2
+    %ior.4 = or i8 %z.ld.1, %z2.ld.1
+    %z.ld.2 = load i8, i8* %z
+    %z2.ld.2 = load i8, i8* %z2
+    %iand.7 = and i8 %z.ld.2, %z2.ld.2
+    %z.ld.3 = load i8, i8* %z
+    %z2.ld.3 = load i8, i8* %z2
+    %ior.5 = or i8 %z.ld.3, %z2.ld.3
+    %z.ld.4 = load i8, i8* %z
+    %z2.ld.4 = load i8, i8* %z2
+    %xor.2 = xor i8 %z.ld.4, %z2.ld.4
+    %z.ld.5 = load i8, i8* %z
+    %z2.ld.5 = load i8, i8* %z2
+    %iand.8 = and i8 %z.ld.5, %z2.ld.5
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -879,12 +899,13 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestMulDiv) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestMulDiv) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
-  Operator optotest[] = {OPERATOR_MULT,OPERATOR_DIV,OPERATOR_MOD};
+  Operator optotest[] = {OPERATOR_MULT, OPERATOR_DIV, OPERATOR_MOD};
 
   Btype *bi16t = be->integer_type(false, 16);
   Btype *bu16t = be->integer_type(true, 16);
@@ -915,26 +936,26 @@
   }
 
   const char *exp = R"RAW_RESULT(
-  store i16 0, i16* %x
-  store i16 0, i16* %y
-  store double 0.000000e+00, double* %z
-  %x.ld.0 = load i16, i16* %x
-  %mul.0 = mul i16 -17, %x.ld.0
-  %x.ld.1 = load i16, i16* %x
-  %div.0 = sdiv i16 -17, %x.ld.1
-  %x.ld.2 = load i16, i16* %x
-  %mod.0 = srem i16 -17, %x.ld.2
-  %y.ld.0 = load i16, i16* %y
-  %mul.1 = mul i16 13, %y.ld.0
-  %y.ld.1 = load i16, i16* %y
-  %div.1 = udiv i16 13, %y.ld.1
-  %y.ld.2 = load i16, i16* %y
-  %mod.1 = urem i16 13, %y.ld.2
-  %z.ld.0 = load double, double* %z
-  %fmul.0 = fmul double 9.000000e+00, %z.ld.0
-  %z.ld.1 = load double, double* %z
-  %fdiv.0 = fdiv double 9.000000e+00, %z.ld.1
-    )RAW_RESULT";
+    store i16 0, i16* %x
+    store i16 0, i16* %y
+    store double 0.000000e+00, double* %z
+    %x.ld.0 = load i16, i16* %x
+    %mul.0 = mul i16 -17, %x.ld.0
+    %x.ld.1 = load i16, i16* %x
+    %div.0 = sdiv i16 -17, %x.ld.1
+    %x.ld.2 = load i16, i16* %x
+    %mod.0 = srem i16 -17, %x.ld.2
+    %y.ld.0 = load i16, i16* %y
+    %mul.1 = mul i16 13, %y.ld.0
+    %y.ld.1 = load i16, i16* %y
+    %div.1 = udiv i16 13, %y.ld.1
+    %y.ld.2 = load i16, i16* %y
+    %mod.1 = urem i16 13, %y.ld.2
+    %z.ld.0 = load double, double* %z
+    %fmul.0 = fmul double 9.000000e+00, %z.ld.0
+    %z.ld.1 = load double, double* %z
+    %fdiv.0 = fdiv double 9.000000e+00, %z.ld.1
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -943,12 +964,13 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestShift) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestShift) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
-  Operator optotest[] = {OPERATOR_LSHIFT,OPERATOR_RSHIFT};
+  Operator optotest[] = {OPERATOR_LSHIFT, OPERATOR_RSHIFT};
 
   Btype *bi64t = be->integer_type(false, 64);
   Btype *bu64t = be->integer_type(true, 64);
@@ -994,31 +1016,31 @@
   }
 
   const char *exp = R"RAW_RESULT(
-      store i64 0, i64* %x
-      store i64 0, i64* %y
-      store i64 0, i64* %s
-      store i32 0, i32* %z
-      %x.ld.0 = load i64, i64* %x
-      %s.ld.0 = load i64, i64* %s
-      %shl.0 = shl i64 %x.ld.0, %s.ld.0
-      %x.ld.1 = load i64, i64* %x
-      %s.ld.1 = load i64, i64* %s
-      %shr.0 = ashr i64 %x.ld.1, %s.ld.1
-      %y.ld.0 = load i64, i64* %y
-      %s.ld.2 = load i64, i64* %s
-      %shl.1 = shl i64 %y.ld.0, %s.ld.2
-      %y.ld.1 = load i64, i64* %y
-      %s.ld.3 = load i64, i64* %s
-      %shr.1 = lshr i64 %y.ld.1, %s.ld.3
-      %x.ld.2 = load i64, i64* %x
-      %z.ld.0 = load i32, i32* %z
-      %zext.0 = zext i32 %z.ld.0 to i64
-      %shl.2 = shl i64 %x.ld.2, %zext.0
-      %z.ld.1 = load i32, i32* %z
-      %y.ld.2 = load i64, i64* %y
-      %trunc.0 = trunc i64 %y.ld.2 to i32
-      %shr.2 = lshr i32 %z.ld.1, %trunc.0
-    )RAW_RESULT";
+    store i64 0, i64* %x
+    store i64 0, i64* %y
+    store i64 0, i64* %s
+    store i32 0, i32* %z
+    %x.ld.0 = load i64, i64* %x
+    %s.ld.0 = load i64, i64* %s
+    %shl.0 = shl i64 %x.ld.0, %s.ld.0
+    %x.ld.1 = load i64, i64* %x
+    %s.ld.1 = load i64, i64* %s
+    %shr.0 = ashr i64 %x.ld.1, %s.ld.1
+    %y.ld.0 = load i64, i64* %y
+    %s.ld.2 = load i64, i64* %s
+    %shl.1 = shl i64 %y.ld.0, %s.ld.2
+    %y.ld.1 = load i64, i64* %y
+    %s.ld.3 = load i64, i64* %s
+    %shr.1 = lshr i64 %y.ld.1, %s.ld.3
+    %x.ld.2 = load i64, i64* %x
+    %z.ld.0 = load i32, i32* %z
+    %zext.0 = zext i32 %z.ld.0 to i64
+    %shl.2 = shl i64 %x.ld.2, %zext.0
+    %z.ld.1 = load i32, i32* %z
+    %y.ld.2 = load i64, i64* %y
+    %trunc.0 = trunc i64 %y.ld.2 to i32
+    %shr.2 = lshr i32 %z.ld.1, %trunc.0
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -1027,8 +1049,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestComplexOps) {
-  FcnTestHarness h;
+TEST_P(BackendExprTests, TestComplexOps) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty);
@@ -1056,158 +1079,158 @@
   }
 
   const char *exp = R"RAW_RESULT(
-  define void @foo(i8* nest %nest.0) #0 {
-  entry:
-    %tmp.12 = alloca { double, double }
-    %tmp.11 = alloca { double, double }
-    %tmp.10 = alloca { double, double }
-    %tmp.9 = alloca { double, double }
-    %tmp.8 = alloca { double, double }
-    %tmp.7 = alloca { double, double }
-    %tmp.6 = alloca { double, double }
-    %tmp.5 = alloca { double, double }
-    %tmp.4 = alloca { double, double }
-    %tmp.3 = alloca { double, double }
-    %tmp.2 = alloca { double, double }
-    %tmp.1 = alloca { double, double }
-    %tmp.0 = alloca { double, double }
-    %x = alloca { double, double }
-    %y = alloca { double, double }
-    %z = alloca { double, double }
-    %b = alloca i8
-    %cast.0 = bitcast { double, double }* %x to i8*
-    %cast.1 = bitcast { double, double }* @const.0 to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 16, i1 false)
-    %cast.2 = bitcast { double, double }* %y to i8*
-    %cast.3 = bitcast { double, double }* @const.0 to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 %cast.3, i64 16, i1 false)
-    %cast.4 = bitcast { double, double }* %z to i8*
-    %cast.5 = bitcast { double, double }* @const.0 to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.4, i8* align 8 %cast.5, i64 16, i1 false)
-    store i8 0, i8* %b
-    %cast.6 = bitcast { double, double }* %tmp.0 to i8*
-    %cast.7 = bitcast { double, double }* %x to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.6, i8* align 8 %cast.7, i64 16, i1 false)
-    %cast.8 = bitcast { double, double }* %tmp.1 to i8*
-    %cast.9 = bitcast { double, double }* %y to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.8, i8* align 8 %cast.9, i64 16, i1 false)
-    %field.0 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 0
-    %.real.ld.0 = load double, double* %field.0
-    %field.1 = getelementptr inbounds { double, double }, { double, double }* %tmp.1, i32 0, i32 0
-    %.real.ld.1 = load double, double* %field.1
-    %fadd.0 = fadd double %.real.ld.0, %.real.ld.1
-    %field.2 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 1
-    %.imag.ld.0 = load double, double* %field.2
-    %field.3 = getelementptr inbounds { double, double }, { double, double }* %tmp.1, i32 0, i32 1
-    %.imag.ld.1 = load double, double* %field.3
-    %fadd.1 = fadd double %.imag.ld.0, %.imag.ld.1
-    %field.4 = getelementptr inbounds { double, double }, { double, double }* %tmp.2, i32 0, i32 0
-    store double %fadd.0, double* %field.4
-    %field.5 = getelementptr inbounds { double, double }, { double, double }* %tmp.2, i32 0, i32 1
-    store double %fadd.1, double* %field.5
-    %cast.10 = bitcast { double, double }* %z to i8*
-    %cast.11 = bitcast { double, double }* %tmp.2 to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.10, i8* align 8 %cast.11, i64 16, i1 false)
-    %cast.12 = bitcast { double, double }* %tmp.3 to i8*
-    %cast.13 = bitcast { double, double }* %x to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.12, i8* align 8 %cast.13, i64 16, i1 false)
-    %cast.14 = bitcast { double, double }* %tmp.4 to i8*
-    %cast.15 = bitcast { double, double }* %y to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.14, i8* align 8 %cast.15, i64 16, i1 false)
-    %field.6 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 0
-    %.real.ld.2 = load double, double* %field.6
-    %field.7 = getelementptr inbounds { double, double }, { double, double }* %tmp.4, i32 0, i32 0
-    %.real.ld.3 = load double, double* %field.7
-    %fsub.0 = fsub double %.real.ld.2, %.real.ld.3
-    %field.8 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 1
-    %.imag.ld.2 = load double, double* %field.8
-    %field.9 = getelementptr inbounds { double, double }, { double, double }* %tmp.4, i32 0, i32 1
-    %.imag.ld.3 = load double, double* %field.9
-    %fsub.1 = fsub double %.imag.ld.2, %.imag.ld.3
-    %field.10 = getelementptr inbounds { double, double }, { double, double }* %tmp.5, i32 0, i32 0
-    store double %fsub.0, double* %field.10
-    %field.11 = getelementptr inbounds { double, double }, { double, double }* %tmp.5, i32 0, i32 1
-    store double %fsub.1, double* %field.11
-    %cast.16 = bitcast { double, double }* %z to i8*
-    %cast.17 = bitcast { double, double }* %tmp.5 to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.16, i8* align 8 %cast.17, i64 16, i1 false)
-    %cast.18 = bitcast { double, double }* %tmp.6 to i8*
-    %cast.19 = bitcast { double, double }* %x to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.18, i8* align 8 %cast.19, i64 16, i1 false)
-    %cast.20 = bitcast { double, double }* %tmp.7 to i8*
-    %cast.21 = bitcast { double, double }* %y to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.20, i8* align 8 %cast.21, i64 16, i1 false)
-    %field.12 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 0
-    %.real.ld.4 = load double, double* %field.12
-    %field.13 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 0
-    %.real.ld.5 = load double, double* %field.13
-    %fmul.0 = fmul double %.real.ld.4, %.real.ld.5
-    %field.14 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 1
-    %.imag.ld.4 = load double, double* %field.14
-    %field.15 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 1
-    %.imag.ld.5 = load double, double* %field.15
-    %fmul.1 = fmul double %.imag.ld.4, %.imag.ld.5
-    %fsub.2 = fsub double %fmul.0, %fmul.1
-    %field.16 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 0
-    %.field.ld.0 = load double, double* %field.16
-    %field.17 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 1
-    %.field.ld.1 = load double, double* %field.17
-    %fmul.2 = fmul double %.field.ld.0, %.field.ld.1
-    %field.18 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 1
-    %.field.ld.2 = load double, double* %field.18
-    %field.19 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 0
-    %.field.ld.3 = load double, double* %field.19
-    %fmul.3 = fmul double %.field.ld.2, %.field.ld.3
-    %fadd.2 = fadd double %fmul.2, %fmul.3
-    %field.20 = getelementptr inbounds { double, double }, { double, double }* %tmp.8, i32 0, i32 0
-    store double %fsub.2, double* %field.20
-    %field.21 = getelementptr inbounds { double, double }, { double, double }* %tmp.8, i32 0, i32 1
-    store double %fadd.2, double* %field.21
-    %cast.22 = bitcast { double, double }* %z to i8*
-    %cast.23 = bitcast { double, double }* %tmp.8 to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.22, i8* align 8 %cast.23, i64 16, i1 false)
-    %cast.24 = bitcast { double, double }* %tmp.9 to i8*
-    %cast.25 = bitcast { double, double }* %x to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.24, i8* align 8 %cast.25, i64 16, i1 false)
-    %cast.26 = bitcast { double, double }* %tmp.10 to i8*
-    %cast.27 = bitcast { double, double }* %y to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.26, i8* align 8 %cast.27, i64 16, i1 false)
-    %field.22 = getelementptr inbounds { double, double }, { double, double }* %tmp.9, i32 0, i32 0
-    %.real.ld.6 = load double, double* %field.22
-    %field.23 = getelementptr inbounds { double, double }, { double, double }* %tmp.10, i32 0, i32 0
-    %.real.ld.7 = load double, double* %field.23
-    %fcmp.0 = fcmp oeq double %.real.ld.6, %.real.ld.7
-    %zext.0 = zext i1 %fcmp.0 to i8
-    %field.24 = getelementptr inbounds { double, double }, { double, double }* %tmp.9, i32 0, i32 1
-    %.imag.ld.6 = load double, double* %field.24
-    %field.25 = getelementptr inbounds { double, double }, { double, double }* %tmp.10, i32 0, i32 1
-    %.imag.ld.7 = load double, double* %field.25
-    %fcmp.1 = fcmp oeq double %.imag.ld.6, %.imag.ld.7
-    %zext.1 = zext i1 %fcmp.1 to i8
-    %iand.0 = and i8 %zext.0, %zext.1
-    store i8 %iand.0, i8* %b
-    %cast.28 = bitcast { double, double }* %tmp.11 to i8*
-    %cast.29 = bitcast { double, double }* %x to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.28, i8* align 8 %cast.29, i64 16, i1 false)
-    %cast.30 = bitcast { double, double }* %tmp.12 to i8*
-    %cast.31 = bitcast { double, double }* %y to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.30, i8* align 8 %cast.31, i64 16, i1 false)
-    %field.26 = getelementptr inbounds { double, double }, { double, double }* %tmp.11, i32 0, i32 0
-    %.real.ld.8 = load double, double* %field.26
-    %field.27 = getelementptr inbounds { double, double }, { double, double }* %tmp.12, i32 0, i32 0
-    %.real.ld.9 = load double, double* %field.27
-    %fcmp.2 = fcmp une double %.real.ld.8, %.real.ld.9
-    %zext.2 = zext i1 %fcmp.2 to i8
-    %field.28 = getelementptr inbounds { double, double }, { double, double }* %tmp.11, i32 0, i32 1
-    %.imag.ld.8 = load double, double* %field.28
-    %field.29 = getelementptr inbounds { double, double }, { double, double }* %tmp.12, i32 0, i32 1
-    %.imag.ld.9 = load double, double* %field.29
-    %fcmp.3 = fcmp une double %.imag.ld.8, %.imag.ld.9
-    %zext.3 = zext i1 %fcmp.3 to i8
-    %ior.0 = or i8 %zext.2, %zext.3
-    store i8 %ior.0, i8* %b
-    ret void
-  }
+    define void @foo(i8* nest %nest.0) #0 {
+    entry:
+      %tmp.12 = alloca { double, double }
+      %tmp.11 = alloca { double, double }
+      %tmp.10 = alloca { double, double }
+      %tmp.9 = alloca { double, double }
+      %tmp.8 = alloca { double, double }
+      %tmp.7 = alloca { double, double }
+      %tmp.6 = alloca { double, double }
+      %tmp.5 = alloca { double, double }
+      %tmp.4 = alloca { double, double }
+      %tmp.3 = alloca { double, double }
+      %tmp.2 = alloca { double, double }
+      %tmp.1 = alloca { double, double }
+      %tmp.0 = alloca { double, double }
+      %x = alloca { double, double }
+      %y = alloca { double, double }
+      %z = alloca { double, double }
+      %b = alloca i8
+      %cast.0 = bitcast { double, double }* %x to i8*
+      %cast.1 = bitcast { double, double }* @const.0 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 16, i1 false)
+      %cast.2 = bitcast { double, double }* %y to i8*
+      %cast.3 = bitcast { double, double }* @const.0 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 %cast.3, i64 16, i1 false)
+      %cast.4 = bitcast { double, double }* %z to i8*
+      %cast.5 = bitcast { double, double }* @const.0 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.4, i8* align 8 %cast.5, i64 16, i1 false)
+      store i8 0, i8* %b
+      %cast.6 = bitcast { double, double }* %tmp.0 to i8*
+      %cast.7 = bitcast { double, double }* %x to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.6, i8* align 8 %cast.7, i64 16, i1 false)
+      %cast.8 = bitcast { double, double }* %tmp.1 to i8*
+      %cast.9 = bitcast { double, double }* %y to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.8, i8* align 8 %cast.9, i64 16, i1 false)
+      %field.0 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 0
+      %.real.ld.0 = load double, double* %field.0
+      %field.1 = getelementptr inbounds { double, double }, { double, double }* %tmp.1, i32 0, i32 0
+      %.real.ld.1 = load double, double* %field.1
+      %fadd.0 = fadd double %.real.ld.0, %.real.ld.1
+      %field.2 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 1
+      %.imag.ld.0 = load double, double* %field.2
+      %field.3 = getelementptr inbounds { double, double }, { double, double }* %tmp.1, i32 0, i32 1
+      %.imag.ld.1 = load double, double* %field.3
+      %fadd.1 = fadd double %.imag.ld.0, %.imag.ld.1
+      %field.4 = getelementptr inbounds { double, double }, { double, double }* %tmp.2, i32 0, i32 0
+      store double %fadd.0, double* %field.4
+      %field.5 = getelementptr inbounds { double, double }, { double, double }* %tmp.2, i32 0, i32 1
+      store double %fadd.1, double* %field.5
+      %cast.10 = bitcast { double, double }* %z to i8*
+      %cast.11 = bitcast { double, double }* %tmp.2 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.10, i8* align 8 %cast.11, i64 16, i1 false)
+      %cast.12 = bitcast { double, double }* %tmp.3 to i8*
+      %cast.13 = bitcast { double, double }* %x to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.12, i8* align 8 %cast.13, i64 16, i1 false)
+      %cast.14 = bitcast { double, double }* %tmp.4 to i8*
+      %cast.15 = bitcast { double, double }* %y to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.14, i8* align 8 %cast.15, i64 16, i1 false)
+      %field.6 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 0
+      %.real.ld.2 = load double, double* %field.6
+      %field.7 = getelementptr inbounds { double, double }, { double, double }* %tmp.4, i32 0, i32 0
+      %.real.ld.3 = load double, double* %field.7
+      %fsub.0 = fsub double %.real.ld.2, %.real.ld.3
+      %field.8 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 1
+      %.imag.ld.2 = load double, double* %field.8
+      %field.9 = getelementptr inbounds { double, double }, { double, double }* %tmp.4, i32 0, i32 1
+      %.imag.ld.3 = load double, double* %field.9
+      %fsub.1 = fsub double %.imag.ld.2, %.imag.ld.3
+      %field.10 = getelementptr inbounds { double, double }, { double, double }* %tmp.5, i32 0, i32 0
+      store double %fsub.0, double* %field.10
+      %field.11 = getelementptr inbounds { double, double }, { double, double }* %tmp.5, i32 0, i32 1
+      store double %fsub.1, double* %field.11
+      %cast.16 = bitcast { double, double }* %z to i8*
+      %cast.17 = bitcast { double, double }* %tmp.5 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.16, i8* align 8 %cast.17, i64 16, i1 false)
+      %cast.18 = bitcast { double, double }* %tmp.6 to i8*
+      %cast.19 = bitcast { double, double }* %x to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.18, i8* align 8 %cast.19, i64 16, i1 false)
+      %cast.20 = bitcast { double, double }* %tmp.7 to i8*
+      %cast.21 = bitcast { double, double }* %y to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.20, i8* align 8 %cast.21, i64 16, i1 false)
+      %field.12 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 0
+      %.real.ld.4 = load double, double* %field.12
+      %field.13 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 0
+      %.real.ld.5 = load double, double* %field.13
+      %fmul.0 = fmul double %.real.ld.4, %.real.ld.5
+      %field.14 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 1
+      %.imag.ld.4 = load double, double* %field.14
+      %field.15 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 1
+      %.imag.ld.5 = load double, double* %field.15
+      %fmul.1 = fmul double %.imag.ld.4, %.imag.ld.5
+      %fsub.2 = fsub double %fmul.0, %fmul.1
+      %field.16 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 0
+      %.field.ld.0 = load double, double* %field.16
+      %field.17 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 1
+      %.field.ld.1 = load double, double* %field.17
+      %fmul.2 = fmul double %.field.ld.0, %.field.ld.1
+      %field.18 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 1
+      %.field.ld.2 = load double, double* %field.18
+      %field.19 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 0
+      %.field.ld.3 = load double, double* %field.19
+      %fmul.3 = fmul double %.field.ld.2, %.field.ld.3
+      %fadd.2 = fadd double %fmul.2, %fmul.3
+      %field.20 = getelementptr inbounds { double, double }, { double, double }* %tmp.8, i32 0, i32 0
+      store double %fsub.2, double* %field.20
+      %field.21 = getelementptr inbounds { double, double }, { double, double }* %tmp.8, i32 0, i32 1
+      store double %fadd.2, double* %field.21
+      %cast.22 = bitcast { double, double }* %z to i8*
+      %cast.23 = bitcast { double, double }* %tmp.8 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.22, i8* align 8 %cast.23, i64 16, i1 false)
+      %cast.24 = bitcast { double, double }* %tmp.9 to i8*
+      %cast.25 = bitcast { double, double }* %x to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.24, i8* align 8 %cast.25, i64 16, i1 false)
+      %cast.26 = bitcast { double, double }* %tmp.10 to i8*
+      %cast.27 = bitcast { double, double }* %y to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.26, i8* align 8 %cast.27, i64 16, i1 false)
+      %field.22 = getelementptr inbounds { double, double }, { double, double }* %tmp.9, i32 0, i32 0
+      %.real.ld.6 = load double, double* %field.22
+      %field.23 = getelementptr inbounds { double, double }, { double, double }* %tmp.10, i32 0, i32 0
+      %.real.ld.7 = load double, double* %field.23
+      %fcmp.0 = fcmp oeq double %.real.ld.6, %.real.ld.7
+      %zext.0 = zext i1 %fcmp.0 to i8
+      %field.24 = getelementptr inbounds { double, double }, { double, double }* %tmp.9, i32 0, i32 1
+      %.imag.ld.6 = load double, double* %field.24
+      %field.25 = getelementptr inbounds { double, double }, { double, double }* %tmp.10, i32 0, i32 1
+      %.imag.ld.7 = load double, double* %field.25
+      %fcmp.1 = fcmp oeq double %.imag.ld.6, %.imag.ld.7
+      %zext.1 = zext i1 %fcmp.1 to i8
+      %iand.0 = and i8 %zext.0, %zext.1
+      store i8 %iand.0, i8* %b
+      %cast.28 = bitcast { double, double }* %tmp.11 to i8*
+      %cast.29 = bitcast { double, double }* %x to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.28, i8* align 8 %cast.29, i64 16, i1 false)
+      %cast.30 = bitcast { double, double }* %tmp.12 to i8*
+      %cast.31 = bitcast { double, double }* %y to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.30, i8* align 8 %cast.31, i64 16, i1 false)
+      %field.26 = getelementptr inbounds { double, double }, { double, double }* %tmp.11, i32 0, i32 0
+      %.real.ld.8 = load double, double* %field.26
+      %field.27 = getelementptr inbounds { double, double }, { double, double }* %tmp.12, i32 0, i32 0
+      %.real.ld.9 = load double, double* %field.27
+      %fcmp.2 = fcmp une double %.real.ld.8, %.real.ld.9
+      %zext.2 = zext i1 %fcmp.2 to i8
+      %field.28 = getelementptr inbounds { double, double }, { double, double }* %tmp.11, i32 0, i32 1
+      %.imag.ld.8 = load double, double* %field.28
+      %field.29 = getelementptr inbounds { double, double }, { double, double }* %tmp.12, i32 0, i32 1
+      %.imag.ld.9 = load double, double* %field.29
+      %fcmp.3 = fcmp une double %.imag.ld.8, %.imag.ld.9
+      %zext.3 = zext i1 %fcmp.3 to i8
+      %ior.0 = or i8 %zext.2, %zext.3
+      store i8 %ior.0, i8* %b
+      ret void
+    }
   )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
@@ -1217,8 +1240,9 @@
   EXPECT_TRUE(isOK && "Block does not have expected contents");
 }
 
-TEST(BackendExprTests, TestComplexExpressions) {
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestComplexExpressions) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -1276,16 +1300,16 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, CreateStringConstantExpressions) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, CreateStringConstantExpressions) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   {
     Bexpression *snil = be->string_constant_expression("");
     const char *exp = R"RAW_RESULT(
-    i8* null
-    )RAW_RESULT";
+        i8* null
+      )RAW_RESULT";
     bool isOK = h.expectValue(snil->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
   }
@@ -1293,7 +1317,7 @@
   {
     Bexpression *sblah = be->string_constant_expression("blah");
     const char *exp = R"RAW_RESULT(
-    i8* getelementptr inbounds ([5 x i8], [5 x i8]* @const.0, i32 0, i32 0)
+      i8* getelementptr inbounds ([5 x i8], [5 x i8]* @const.0, i32 0, i32 0)
     )RAW_RESULT";
     bool isOK = h.expectValue(sblah->value(), exp);
     EXPECT_TRUE(isOK && "Value does not have expected contents");
@@ -1303,9 +1327,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestConditionalExpression1) {
-
-  FcnTestHarness h;
+TEST_P(BackendExprTests, TestConditionalExpression1) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty1 = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty1);
@@ -1327,31 +1351,31 @@
   h.mkExprStmt(condex);
 
   const char *exp = R"RAW_RESULT(
-define void @foo(i8* nest %nest.0) #0 {
-entry:
-  %a = alloca i64
-  %b = alloca i64
-  store i64 0, i64* %a
-  store i64 0, i64* %b
-  %a.ld.0 = load i64, i64* %a
-  %b.ld.0 = load i64, i64* %b
-  %icmp.0 = icmp slt i64 %a.ld.0, %b.ld.0
-  %zext.0 = zext i1 %icmp.0 to i8
-  %trunc.0 = trunc i8 %zext.0 to i1
-  br i1 %trunc.0, label %then.0, label %else.0
+    define void @foo(i8* nest %nest.0) #0 {
+    entry:
+      %a = alloca i64
+      %b = alloca i64
+      store i64 0, i64* %a
+      store i64 0, i64* %b
+      %a.ld.0 = load i64, i64* %a
+      %b.ld.0 = load i64, i64* %b
+      %icmp.0 = icmp slt i64 %a.ld.0, %b.ld.0
+      %zext.0 = zext i1 %icmp.0 to i8
+      %trunc.0 = trunc i8 %zext.0 to i1
+      br i1 %trunc.0, label %then.0, label %else.0
 
-then.0:                                           ; preds = %entry
-  call void @foo(i8* nest undef)
-  br label %fallthrough.0
+    then.0:                                           ; preds = %entry
+      call void @foo(i8* nest undef)
+      br label %fallthrough.0
 
-fallthrough.0:                                    ; preds = %else.0, %then.0
-  ret void
+    fallthrough.0:                                    ; preds = %else.0, %then.0
+      ret void
 
-else.0:                                           ; preds = %entry
-  call void @foo(i8* nest undef)
-  br label %fallthrough.0
-}
-    )RAW_RESULT";
+    else.0:                                           ; preds = %entry
+      call void @foo(i8* nest undef)
+      br label %fallthrough.0
+    }
+  )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1360,9 +1384,9 @@
   EXPECT_TRUE(isOK && "Block does not have expected contents");
 }
 
-TEST(BackendExprTests, TestConditionalExpression2) {
-
-  FcnTestHarness h;
+TEST_P(BackendExprTests, TestConditionalExpression2) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty1 = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty1);
@@ -1377,7 +1401,7 @@
   Bexpression *ve = be->var_expression(pv1, loc);
   Bexpression *cmp = be->binary_expression(OPERATOR_LT,
                                            mkInt64Const(be, int64_t(3)),
-                                           mkInt64Const(be, int64_t(4)), loc);
+                                          mkInt64Const(be, int64_t(4)), loc);
   Bexpression *condex = be->conditional_expression(func, ve->btype(),
                                                    cmp, call1,
                                                    ve, loc);
@@ -1401,7 +1425,7 @@
       store i64 %a.ld.0, i64* %tmpv.0
       br label %fallthrough.0
     }
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1410,9 +1434,8 @@
   EXPECT_TRUE(isOK && "Block does not have expected contents");
 }
 
-TEST(BackendExprTests, TestConditionalExpression3) {
-
-  FcnTestHarness h;
+TEST(BackendExprTests, TestConditionalExpression3Amd64) {
+  FcnTestHarness h(llvm::CallingConv::X86_64_SysV);
   Llvm_backend *be = h.be();
   Btype *bi32t = be->integer_type(false, 32);
   Btype *abt = be->array_type(bi32t, mkInt64Const(be, int64_t(16)));
@@ -1437,39 +1460,38 @@
                                                  vep0, bzero, loc);
   h.mkLocal("a", s2t, cond);
 
-
   const char *exp = R"RAW_RESULT(
-define void @foo({ [16 x i32], i32 }* sret %sret.formal.0, i8* nest %nest.0, { [16 x i32], i32 }* byval %p0, i32 %p1) #0 {
-entry:
-  %p1.addr = alloca i32
-  %a = alloca { [16 x i32], i32 }
-  %tmpv.0 = alloca { [16 x i32], i32 }
-  store i32 %p1, i32* %p1.addr
-  %p1.ld.0 = load i32, i32* %p1.addr
-  %icmp.0 = icmp slt i32 %p1.ld.0, 7
-  %zext.0 = zext i1 %icmp.0 to i8
-  %trunc.0 = trunc i8 %zext.0 to i1
-  br i1 %trunc.0, label %then.0, label %else.0
+    define void @foo({ [16 x i32], i32 }* sret %sret.formal.0, i8* nest %nest.0, { [16 x i32], i32 }* byval %p0, i32 %p1) #0 {
+    entry:
+      %p1.addr = alloca i32
+      %a = alloca { [16 x i32], i32 }
+      %tmpv.0 = alloca { [16 x i32], i32 }
+      store i32 %p1, i32* %p1.addr
+      %p1.ld.0 = load i32, i32* %p1.addr
+      %icmp.0 = icmp slt i32 %p1.ld.0, 7
+      %zext.0 = zext i1 %icmp.0 to i8
+      %trunc.0 = trunc i8 %zext.0 to i1
+      br i1 %trunc.0, label %then.0, label %else.0
 
-then.0:                                           ; preds = %entry
-  %cast.0 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
-  %cast.1 = bitcast { [16 x i32], i32 }* %p0 to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 %cast.1, i64 68, i1 false)
-  br label %fallthrough.0
+    then.0:                                           ; preds = %entry
+      %cast.0 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
+      %cast.1 = bitcast { [16 x i32], i32 }* %p0 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 %cast.1, i64 68, i1 false)
+      br label %fallthrough.0
 
-fallthrough.0:                                    ; preds = %else.0, %then.0
-  %cast.4 = bitcast { [16 x i32], i32 }* %a to i8*
-  %cast.5 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.4, i8* align 4 %cast.5, i64 68, i1 false)
-  ret void
+    fallthrough.0:                                    ; preds = %else.0, %then.0
+      %cast.4 = bitcast { [16 x i32], i32 }* %a to i8*
+      %cast.5 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.4, i8* align 4 %cast.5, i64 68, i1 false)
+      ret void
 
-else.0:                                           ; preds = %entry
-  %cast.2 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
-  %cast.3 = bitcast { [16 x i32], i32 }* @const.0 to i8*
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 %cast.3, i64 68, i1 false)
-  br label %fallthrough.0
-}
-    )RAW_RESULT";
+    else.0:                                           ; preds = %entry
+      %cast.2 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
+      %cast.3 = bitcast { [16 x i32], i32 }* @const.0 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 %cast.3, i64 68, i1 false)
+      br label %fallthrough.0
+    }
+  )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1478,9 +1500,9 @@
   EXPECT_TRUE(isOK && "Block does not have expected contents");
 }
 
-TEST(BackendExprTests, TestCompoundExpression) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestCompoundExpression) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -1491,8 +1513,8 @@
   Btype *bi64t = be->integer_type(false, 64);
   Bvariable *xv = h.mkLocal("x", bi64t);
   Bexpression *vex = be->var_expression(xv, loc);
-  Bstatement *st =  be->assignment_statement(func, vex,
-                                             mkInt64Const(be, 5), loc);
+  Bstatement *st = be->assignment_statement(func, vex,
+                                            mkInt64Const(be, 5), loc);
   Bexpression *vex2 = be->var_expression(xv, loc);
   Bexpression *ce = be->compound_expression(st, vex2, loc);
   Bstatement *es = be->expression_statement(func, ce);
@@ -1513,7 +1535,7 @@
         %x.ld.0 = load i64, i64* %x
         ret i64 0
       }
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1523,9 +1545,9 @@
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-TEST(BackendExprTests, TestCompoundExpression2) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestCompoundExpression2) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -1576,7 +1598,7 @@
         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 %cast.3, i64 16, i1 false)
         ret i64 0
       }
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1586,9 +1608,9 @@
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-TEST(BackendExprTests, TestLhsConditionalExpression) {
-
-  FcnTestHarness h;
+TEST_P(BackendExprTests, TestLhsConditionalExpression) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   Btype *bi32t = be->integer_type(false, 32);
   BFunctionType *befty1 = mkFuncTyp(be,
@@ -1606,42 +1628,41 @@
   Bexpression *cmp = be->binary_expression(OPERATOR_EQEQ, vex, npe, loc);
   Bexpression *ver0 = be->var_expression(p0v, loc);
   Bexpression *ver1 = be->var_expression(p1v, loc);
-  Bexpression *guard =
-      be->conditional_expression(func, be->pointer_type(bi32t), cmp,
-                                 ver1, ver0, loc);
+  Bexpression *guard = be->conditional_expression(func, be->pointer_type(bi32t), cmp,
+                                                  ver1, ver0, loc);
   Bexpression *dex = be->indirect_expression(bi32t, guard, false, loc);
   h.mkAssign(dex, mkInt32Const(be, 7));
 
   const char *exp = R"RAW_RESULT(
-      define void @foo(i8* nest %nest.0, i32* %p0, i32* %p1) #0 {
-      entry:
-        %p0.addr = alloca i32*
-        %p1.addr = alloca i32*
-        %tmpv.0 = alloca i32*
-        store i32* %p0, i32** %p0.addr
-        store i32* %p1, i32** %p1.addr
-        %p0.ld.0 = load i32*, i32** %p0.addr
-        %icmp.0 = icmp eq i32* %p0.ld.0, null
-        %zext.0 = zext i1 %icmp.0 to i8
-        %trunc.0 = trunc i8 %zext.0 to i1
-        br i1 %trunc.0, label %then.0, label %else.0
+    define void @foo(i8* nest %nest.0, i32* %p0, i32* %p1) #0 {
+    entry:
+      %p0.addr = alloca i32*
+      %p1.addr = alloca i32*
+      %tmpv.0 = alloca i32*
+      store i32* %p0, i32** %p0.addr
+      store i32* %p1, i32** %p1.addr
+      %p0.ld.0 = load i32*, i32** %p0.addr
+      %icmp.0 = icmp eq i32* %p0.ld.0, null
+      %zext.0 = zext i1 %icmp.0 to i8
+      %trunc.0 = trunc i8 %zext.0 to i1
+      br i1 %trunc.0, label %then.0, label %else.0
 
-      then.0:                                           ; preds = %entry
-        %p1.ld.0 = load i32*, i32** %p1.addr
-        store i32* %p1.ld.0, i32** %tmpv.0
-        br label %fallthrough.0
+    then.0:                                           ; preds = %entry
+      %p1.ld.0 = load i32*, i32** %p1.addr
+      store i32* %p1.ld.0, i32** %tmpv.0
+      br label %fallthrough.0
 
-      fallthrough.0:                                ; preds = %else.0, %then.0
-        %tmpv.0.ld.0 = load i32*, i32** %tmpv.0
-        store i32 7, i32* %tmpv.0.ld.0
-        ret void
+    fallthrough.0:                                ; preds = %else.0, %then.0
+      %tmpv.0.ld.0 = load i32*, i32** %tmpv.0
+      store i32 7, i32* %tmpv.0.ld.0
+      ret void
 
-      else.0:                                           ; preds = %entry
-        %p0.ld.1 = load i32*, i32** %p0.addr
-        store i32* %p0.ld.1, i32** %tmpv.0
-        br label %fallthrough.0
-      }
-    )RAW_RESULT";
+    else.0:                                           ; preds = %entry
+      %p0.ld.1 = load i32*, i32** %p0.addr
+      store i32* %p0.ld.1, i32** %tmpv.0
+      br label %fallthrough.0
+    }
+  )RAW_RESULT";
 
   bool broken = h.finish(StripDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
@@ -1651,9 +1672,9 @@
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-TEST(BackendExprTests, TestUnaryExpression) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestUnaryExpression) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -1686,25 +1707,25 @@
   h.mkLocal("r", bf64t, be->unary_expression(OPERATOR_MINUS, veq, loc));
 
   const char *exp = R"RAW_RESULT(
-      store i8 0, i8* %x
-      %x.ld.0 = load i8, i8* %x
-      %icmp.0 = icmp ne i8 %x.ld.0, 0
-      %xor.0 = xor i1 %icmp.0, true
-      %zext.0 = zext i1 %xor.0 to i8
-      store i8 %zext.0, i8* %y
-      store i32 0, i32* %a
-      %a.ld.0 = load i32, i32* %a
-      %sub.0 = sub i32 0, %a.ld.0
-      store i32 %sub.0, i32* %b
-      store i64 0, i64* %z
-      %z.ld.0 = load i64, i64* %z
-      %xor.1 = xor i64 %z.ld.0, -1
-      store i64 %xor.1, i64* %w
-      store double 0.000000e+00, double* %q
-      %q.ld.0 = load double, double* %q
-      %fsub.0 = fsub double -0.000000e+00, %q.ld.0
-      store double %fsub.0, double* %r
-    )RAW_RESULT";
+    store i8 0, i8* %x
+    %x.ld.0 = load i8, i8* %x
+    %icmp.0 = icmp ne i8 %x.ld.0, 0
+    %xor.0 = xor i1 %icmp.0, true
+    %zext.0 = zext i1 %xor.0 to i8
+    store i8 %zext.0, i8* %y
+    store i32 0, i32* %a
+    %a.ld.0 = load i32, i32* %a
+    %sub.0 = sub i32 0, %a.ld.0
+    store i32 %sub.0, i32* %b
+    store i64 0, i64* %z
+    %z.ld.0 = load i64, i64* %z
+    %xor.1 = xor i64 %z.ld.0, -1
+    store i64 %xor.1, i64* %w
+    store double 0.000000e+00, double* %q
+    %q.ld.0 = load double, double* %q
+    %fsub.0 = fsub double -0.000000e+00, %q.ld.0
+    store double %fsub.0, double* %r
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -1713,18 +1734,18 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestCallArgConversions) {
-
-  FcnTestHarness h;
+TEST_P(BackendExprTests, TestCallArgConversions) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   Btype *bi8t = be->integer_type(false, 8);
   Btype *bi32t = be->integer_type(false, 32);
   Btype *bi64t = be->integer_type(false, 64);
   BFunctionType *befty1 = mkFuncTyp(be,
-                            L_PARM, be->pointer_type(bi8t),
-                            L_PARM, be->pointer_type(bi32t),
-                            L_PARM, be->pointer_type(bi64t),
-                            L_END);
+                                    L_PARM, be->pointer_type(bi8t),
+                                    L_PARM, be->pointer_type(bi32t),
+                                    L_PARM, be->pointer_type(bi64t),
+                                    L_END);
   Bfunction *func = h.mkFunction("foo", befty1);
   Location loc;
 
@@ -1733,8 +1754,8 @@
   h.mkExprStmt(call1);
 
   const char *exp = R"RAW_RESULT(
-     call addrspace(0) void @foo(i8* nest undef, i8* null, i32* null, i64* null)
-    )RAW_RESULT";
+    call addrspace(0) void @foo(i8* nest undef, i8* null, i32* null, i64* null)
+  )RAW_RESULT";
 
   // Note that this
   bool isOK = h.expectBlock(exp);
@@ -1744,9 +1765,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestStringDuplication) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestStringDuplication) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   Bexpression *bst = be->string_constant_expression("abc");
@@ -1759,9 +1780,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendExprTests, TestImmutableStructReferenceDuplication) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendExprTests, TestImmutableStructReferenceDuplication) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc = h.loc();
 
@@ -1777,4 +1798,4 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendFcnTests.cpp b/unittests/BackendCore/BackendFcnTests.cpp
index 8e94c3c..8a7e9bb 100644
--- a/unittests/BackendCore/BackendFcnTests.cpp
+++ b/unittests/BackendCore/BackendFcnTests.cpp
@@ -16,10 +16,20 @@
 
 namespace {
 
-TEST(BackendFcnTests, MakeEmptyFunction) {
+class BackendFcnTests : public testing::TestWithParam<llvm::CallingConv::ID> {};
 
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendFcnTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendFcnTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendFcnTests, MakeEmptyFunction) {
+  auto cc = GetParam();
   // Create empty function
-  FcnTestHarness h;
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty1 = mkFuncTyp(be, L_END);
   h.mkFunction("foo", befty1);
@@ -34,10 +44,10 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendFcnTests, MakeFuncWithLotsOfArgs) {
-
+TEST_P(BackendFcnTests, MakeFuncWithLotsOfArgs) {
+  auto cc = GetParam();
   // Create empty function
-  FcnTestHarness h;
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   Btype *bi32t = be->integer_type(false, 32);
   Btype *bi64t = be->integer_type(false, 64);
@@ -66,10 +76,10 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendFcnTests, MakeFunction) {
+TEST_P(BackendFcnTests, MakeFunction) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   Btype *bi64t = be->integer_type(false, 64);
   Btype *bi32t = be->integer_type(false, 32);
@@ -134,10 +144,10 @@
   EXPECT_EQ(mistake, be_error_fcn);
 }
 
-TEST(BackendFcnTests, BuiltinFunctionsMisc) {
+TEST_P(BackendFcnTests, BuiltinFunctionsMisc) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   std::unordered_set<Bfunction *> results;
   std::vector<std::string> tocheck = {
@@ -158,10 +168,10 @@
   EXPECT_TRUE(results.size() == tocheck.size());
 }
 
-TEST(BackendFcnTests, BuiltinFunctionsTrig) {
+TEST_P(BackendFcnTests, BuiltinFunctionsTrig) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   std::unordered_set<Bfunction *> results;
   std::vector<std::string> tocheck = {
@@ -187,20 +197,20 @@
   EXPECT_TRUE(results.size() == tocheck.size());
 }
 
-TEST(BackendFcnTests, MakeBlocks) {
+TEST_P(BackendFcnTests, MakeBlocks) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
   Bfunction *bfcn = mkFunci32o64(be.get(), "foo");
   const std::vector<Bvariable *> vars;
   Bblock *bb = be->block(bfcn, nullptr, vars, Location(), Location());
   ASSERT_TRUE(bb != nullptr);
 }
 
-TEST(BackendFcnTests, MakeFuncWithRecursiveTypeParam) {
-
+TEST_P(BackendFcnTests, MakeFuncWithRecursiveTypeParam) {
+  auto cc = GetParam();
   // Create empty function
-  FcnTestHarness h;
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -239,9 +249,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendFcnTests, MakeMultipleDeclarations) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendFcnTests, MakeMultipleDeclarations) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -270,8 +280,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendFcnTests, TestIntrinsicCall) {
-  FcnTestHarness h("foo");
+TEST_P(BackendFcnTests, TestIntrinsicCall) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -281,7 +292,7 @@
 
   // __builtin_ctzll(x);
   Bfunction *bfcn = be->lookup_builtin("__builtin_ctzll");
-  //Bexpression *fnexpr = be->function_code_expression(bfcn, loc);
+  // Bexpression *fnexpr = be->function_code_expression(bfcn, loc);
   Bexpression *ve = be->var_expression(x, loc);
   Bexpression *call = h.mkCallExpr(be, bfcn, ve, nullptr);
   h.mkExprStmt(call);
@@ -299,8 +310,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendFcnTests, TestCallMemBuiltins) {
-  FcnTestHarness h("foo");
+TEST_P(BackendFcnTests, TestCallMemBuiltins) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -313,58 +325,56 @@
 
   // memcmp(&x,&y,sizeof(x))
   {
-  Bfunction *bmemcmp = be->lookup_builtin("memcmp");
-  Bexpression *vex = be->var_expression(x, loc);
-  Bexpression *vey = be->var_expression(y, loc);
-  Bexpression *call =
-      h.mkCallExpr(be, bmemcmp,
-                   be->address_expression(vex, loc),
-                   be->address_expression(vey, loc),
-                   mkUint64Const(be, be->type_size(bu64t)),
-                   nullptr);
-  h.mkExprStmt(call);
+    Bfunction *bmemcmp = be->lookup_builtin("memcmp");
+    Bexpression *vex = be->var_expression(x, loc);
+    Bexpression *vey = be->var_expression(y, loc);
+    Bexpression *call =
+        h.mkCallExpr(be, bmemcmp,
+                     be->address_expression(vex, loc),
+                     be->address_expression(vey, loc),
+                     mkUint64Const(be, be->type_size(bu64t)),
+                     nullptr);
+    h.mkExprStmt(call);
   }
 
   // memmove(&x,&y,sizeof(x))
   {
-  Bfunction *bmemmove = be->lookup_builtin("memmove");
-  Bexpression *vex = be->var_expression(x, loc);
-  Bexpression *vey = be->var_expression(y, loc);
-  Bexpression *call =
-      h.mkCallExpr(be, bmemmove,
-                   be->address_expression(vex, loc),
-                   be->address_expression(vey, loc),
-                   mkUint64Const(be, be->type_size(bu64t)),
-                   nullptr);
-  h.mkExprStmt(call);
+    Bfunction *bmemmove = be->lookup_builtin("memmove");
+    Bexpression *vex = be->var_expression(x, loc);
+    Bexpression *vey = be->var_expression(y, loc);
+    Bexpression *call =
+        h.mkCallExpr(be, bmemmove,
+                     be->address_expression(vex, loc),
+                     be->address_expression(vey, loc),
+                     mkUint64Const(be, be->type_size(bu64t)),
+                     nullptr);
+    h.mkExprStmt(call);
   }
 
   // memcpy(&y,&x,sizeof(y))
   {
-  Bfunction *bmemcpy = be->lookup_builtin("memcpy");
-  Bexpression *vey = be->var_expression(y, loc);
-  Bexpression *vex = be->var_expression(x, loc);
-  Bexpression *call =
-      h.mkCallExpr(be, bmemcpy,
-                   be->address_expression(vey, loc),
-                   be->address_expression(vex, loc),
-                   mkUint64Const(be, be->type_size(bu64t)),
-                   nullptr);
-  h.mkExprStmt(call);
+    Bfunction *bmemcpy = be->lookup_builtin("memcpy");
+    Bexpression *vey = be->var_expression(y, loc);
+    Bexpression *vex = be->var_expression(x, loc);
+    Bexpression *call =
+        h.mkCallExpr(be, bmemcpy, be->address_expression(vey, loc),
+                     be->address_expression(vex, loc),
+                     mkUint64Const(be, be->type_size(bu64t)), nullptr);
+    h.mkExprStmt(call);
   }
 
   const char *exp = R"RAW_RESULT(
-  store i64 0, i64* %x
-  store i64 10101, i64* %y
-  %cast.0 = bitcast i64* %x to i8*
-  %cast.1 = bitcast i64* %y to i8*
-  %call.0 = call addrspace(0) i32 @memcmp(i8* %cast.0, i8* %cast.1, i64 8)
-  %cast.2 = bitcast i64* %x to i8*
-  %cast.3 = bitcast i64* %y to i8*
-  call addrspace(0) void @llvm.memmove.p0i8.p0i8.i64(i8* %cast.2, i8* %cast.3, i64 8, i1 false)
-  %cast.4 = bitcast i64* %y to i8*
-  %cast.5 = bitcast i64* %x to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* %cast.4, i8* %cast.5, i64 8, i1 false)
+    store i64 0, i64* %x
+    store i64 10101, i64* %y
+    %cast.0 = bitcast i64* %x to i8*
+    %cast.1 = bitcast i64* %y to i8*
+    %call.0 = call addrspace(0) i32 @memcmp(i8* %cast.0, i8* %cast.1, i64 8)
+    %cast.2 = bitcast i64* %x to i8*
+    %cast.3 = bitcast i64* %y to i8*
+    call addrspace(0) void @llvm.memmove.p0i8.p0i8.i64(i8* %cast.2, i8* %cast.3, i64 8, i1 false)
+    %cast.4 = bitcast i64* %y to i8*
+    %cast.5 = bitcast i64* %x to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* %cast.4, i8* %cast.5, i64 8, i1 false)
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -374,8 +384,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendFcnTests, TestMultipleExternalFcnsWithSameName) {
-  FcnTestHarness h("foo");
+TEST_P(BackendFcnTests, TestMultipleExternalFcnsWithSameName) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -414,11 +425,11 @@
   h.mkLocal("y", bi32t, call32);
 
   const char *exp = R"RAW_RESULT(
-     %call.0 = call addrspace(0) i64 @syscall(i8* nest undef, i64 64)
-     store i64 %call.0, i64* %x
-     %call.1 = call addrspace(0) i32 bitcast (i64 (i8*, i64)*
-           @syscall to i32 (i8*, i32)*)(i8* nest undef, i32 32)
-     store i32 %call.1, i32* %y
+    %call.0 = call addrspace(0) i64 @syscall(i8* nest undef, i64 64)
+    store i64 %call.0, i64* %x
+    %call.1 = call addrspace(0) i32 bitcast (i64 (i8*, i64)*
+          @syscall to i32 (i8*, i32)*)(i8* nest undef, i32 32)
+    store i32 %call.1, i32* %y
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -428,8 +439,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendFcnTests, TestDeclAndDefWithSameName) {
-  FcnTestHarness h("foo");
+TEST_P(BackendFcnTests, TestDeclAndDefWithSameName) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -504,4 +516,4 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendNodeTests.cpp b/unittests/BackendCore/BackendNodeTests.cpp
index 944e5e1..83416ea 100644
--- a/unittests/BackendCore/BackendNodeTests.cpp
+++ b/unittests/BackendCore/BackendNodeTests.cpp
@@ -18,9 +18,20 @@
 
 namespace {
 
+class BackendNodeTests : public testing::TestWithParam<llvm::CallingConv::ID> {
+};
+
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendNodeTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendNodeTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
 class SimpleVisitor {
  public:
-  SimpleVisitor(unsigned stopAt = 0xffffffff) : stopAt_(stopAt) { }
+  SimpleVisitor(unsigned stopAt = 0xffffffff) : stopAt_(stopAt) {}
 
   std::pair<VisitDisp, Bnode *> visitNodePre(Bnode *node) {
     ss_ << "node " << node->flavstr() << " pre " << id(node) << "\n";
@@ -56,9 +67,9 @@
   unsigned stopAt_;
 };
 
-TEST(BackendNodeTests, VerifyVisitorBehavior) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendNodeTests, VerifyVisitorBehavior) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -111,7 +122,7 @@
     node deref post 17
     post child deref 18 17
     node - post 18
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   std::string reason;
   bool equal = difftokens(exp, vis.str(), reason);
@@ -127,9 +138,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendNodeTests, CloneSubtree) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendNodeTests, CloneSubtree) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc = h.loc();
 
@@ -152,14 +163,14 @@
   EXPECT_NE(add, matclone);
 
   const char *exp = R"RAW_RESULT(
-  %x.ld.0 = load i32, i32* %x
-  %z.ld.0 = load i16, i16* %z
-  %sext.0 = sext i16 %z.ld.0 to i32
-  %add.0 = add i32 %x.ld.0, %sext.0
-  %y.ld.0 = load i32*, i32** %y
-  %.ld.0 = load i32, i32* %y.ld.0
-  %add.1 = add i32 %add.0, %.ld.0
-    )RAW_RESULT";
+    %x.ld.0 = load i32, i32* %x
+    %z.ld.0 = load i16, i16* %z
+    %sext.0 = sext i16 %z.ld.0 to i32
+    %add.0 = add i32 %x.ld.0, %sext.0
+    %y.ld.0 = load i32*, i32** %y
+    %.ld.0 = load i32, i32* %y.ld.0
+    %add.1 = add i32 %add.0, %.ld.0
+  )RAW_RESULT";
 
   bool isOK = h.expectRepr(matadd, exp);
   EXPECT_TRUE(isOK && "expr does not have expected contents");
@@ -171,12 +182,11 @@
 
   bool broken = h.finish(PreserveDebugInfo);
   EXPECT_FALSE(broken && "Module failed to verify.");
-
 }
 
-TEST(BackendNodeTests, FixSharing) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendNodeTests, FixSharing) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc = h.loc();
 
@@ -195,16 +205,16 @@
   Bexpression *matadd = be->materialize(add);
 
   const char *exp2 = R"RAW_RESULT(
-  %field.0 = getelementptr inbounds { { i32*, i32 }, { i32*, i32 } }, { { i32*, i32 }, { i32*, i32 } }* %x, i32 0, i32 0
-  %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %field.0, i32 0, i32 0
-  %x.field.field.ld.0 = load i32*, i32** %field.1
-  %.ld.0 = load i32, i32* %x.field.field.ld.0
-  %field.2 = getelementptr inbounds { { i32*, i32 }, { i32*, i32 } }, { { i32*, i32 }, { i32*, i32 } }* %x, i32 0, i32 0
-  %field.3 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %field.2, i32 0, i32 0
-  %.field.field.ld.0 = load i32*, i32** %field.3
-  %.ld.1 = load i32, i32* %.field.field.ld.0
-  %add.0 = add i32 %.ld.0, %.ld.1
-    )RAW_RESULT";
+    %field.0 = getelementptr inbounds { { i32*, i32 }, { i32*, i32 } }, { { i32*, i32 }, { i32*, i32 } }* %x, i32 0, i32 0
+    %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %field.0, i32 0, i32 0
+    %x.field.field.ld.0 = load i32*, i32** %field.1
+    %.ld.0 = load i32, i32* %x.field.field.ld.0
+    %field.2 = getelementptr inbounds { { i32*, i32 }, { i32*, i32 } }, { { i32*, i32 }, { i32*, i32 } }* %x, i32 0, i32 0
+    %field.3 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %field.2, i32 0, i32 0
+    %.field.field.ld.0 = load i32*, i32** %field.3
+    %.ld.1 = load i32, i32* %.field.field.ld.0
+    %add.0 = add i32 %.ld.0, %.ld.1
+  )RAW_RESULT";
 
   bool isOK = h.expectRepr(matadd, exp2);
   EXPECT_TRUE(isOK && "expr does not have expected contents");
@@ -215,4 +225,4 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendPointerExprTests.cpp b/unittests/BackendCore/BackendPointerExprTests.cpp
index 70da0e8..e8a24fe 100644
--- a/unittests/BackendCore/BackendPointerExprTests.cpp
+++ b/unittests/BackendCore/BackendPointerExprTests.cpp
@@ -17,8 +17,20 @@
 
 namespace {
 
-TEST(BackendPointerExprTests, TestAddrAndIndirection) {
-  FcnTestHarness h("foo");
+class BackendPointerExprTests
+    : public testing::TestWithParam<llvm::CallingConv::ID> {};
+
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendPointerExprTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendPointerExprTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendPointerExprTests, TestAddrAndIndirection) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -68,7 +80,7 @@
     store i64 %.ld.0, i64* %y
     %x.ld.1 = load i64*, i64** %x
     store i64 3, i64* %x.ld.1
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -77,9 +89,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendPointerExprTests, CreateFunctionCodeExpression) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendPointerExprTests, CreateFunctionCodeExpression) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -118,17 +130,17 @@
   h.mkAssign(vex3, rvex3);
 
   const char *exp = R"RAW_RESULT(
-  %cast.0 = bitcast { i64 }* %fdloc1 to i8*
-  %cast.1 = bitcast { i64 }* @const.0 to i8*
-  call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 8, i1 false)
-  store { i64 }* %fdloc1, { i64 }** %fploc1
-  store { i64 (i8*, i32, i32, i64*)* }* null, { i64 (i8*, i32, i32, i64*)* }** %fploc2
-  %fploc1.ld.0 = load { i64 }*, { i64 }** %fploc1
-  %cast.2 = bitcast { i64 }* %fploc1.ld.0 to { i64 (i8*, i32, i32, i64*)* }*
-  store { i64 (i8*, i32, i32, i64*)* }* %cast.2, { i64 (i8*, i32, i32, i64*)* }** %fploc2
-  %fploc2.ld.0 = load { i64 (i8*, i32, i32, i64*)* }*, { i64 (i8*, i32, i32, i64*)* }** %fploc2
-  %cast.3 = bitcast { i64 (i8*, i32, i32, i64*)* }* %fploc2.ld.0 to { i64 }*
-  store { i64 }* %cast.3, { i64 }** %fploc1
+    %cast.0 = bitcast { i64 }* %fdloc1 to i8*
+    %cast.1 = bitcast { i64 }* @const.0 to i8*
+    call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 %cast.1, i64 8, i1 false)
+    store { i64 }* %fdloc1, { i64 }** %fploc1
+    store { i64 (i8*, i32, i32, i64*)* }* null, { i64 (i8*, i32, i32, i64*)* }** %fploc2
+    %fploc1.ld.0 = load { i64 }*, { i64 }** %fploc1
+    %cast.2 = bitcast { i64 }* %fploc1.ld.0 to { i64 (i8*, i32, i32, i64*)* }*
+    store { i64 (i8*, i32, i32, i64*)* }* %cast.2, { i64 (i8*, i32, i32, i64*)* }** %fploc2
+    %fploc2.ld.0 = load { i64 (i8*, i32, i32, i64*)* }*, { i64 (i8*, i32, i32, i64*)* }** %fploc2
+    %cast.3 = bitcast { i64 (i8*, i32, i32, i64*)* }* %fploc2.ld.0 to { i64 }*
+    store { i64 }* %cast.3, { i64 }** %fploc1
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -138,9 +150,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendPointerExprTests, CreateNilPointerExpression) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendPointerExprTests, CreateNilPointerExpression) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   // Manufacture a nil pointer expression
@@ -177,17 +189,17 @@
   }
 
   const char *exp2 = R"RAW_RESULT(
-      store i8 0, i8* %b1
-      store i8* null, i8** %pb1
-      %pb1.ld.0 = load i8*, i8** %pb1
-      %icmp.0 = icmp eq i8* %pb1.ld.0, null
-      %zext.0 = zext i1 %icmp.0 to i8
-      store i8 %zext.0, i8* %b1
-      %pb1.ld.1 = load i8*, i8** %pb1
-      %icmp.1 = icmp eq i8* null, %pb1.ld.1
-      %zext.1 = zext i1 %icmp.1 to i8
-      store i8 %zext.1, i8* %b1
-    )RAW_RESULT";
+    store i8 0, i8* %b1
+    store i8* null, i8** %pb1
+    %pb1.ld.0 = load i8*, i8** %pb1
+    %icmp.0 = icmp eq i8* %pb1.ld.0, null
+    %zext.0 = zext i1 %icmp.0 to i8
+    store i8 %zext.0, i8* %b1
+    %pb1.ld.1 = load i8*, i8** %pb1
+    %icmp.1 = icmp eq i8* null, %pb1.ld.1
+    %zext.1 = zext i1 %icmp.1 to i8
+    store i8 %zext.1, i8* %b1
+  )RAW_RESULT";
 
   bool isOK2 = h.expectBlock(exp2);
   EXPECT_TRUE(isOK2 && "Block does not have expected contents");
@@ -196,8 +208,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendPointerExprTests, TestDerefNilPointer) {
-  FcnTestHarness h("foo");
+TEST_P(BackendPointerExprTests, TestDerefNilPointer) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -227,7 +240,7 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendPointerExprTests, CircularPointerExpressions1) {
+TEST_P(BackendPointerExprTests, CircularPointerExpressions1) {
 
   // This testpoint is intended to verify handling of expressions
   // involving circular pointer types. Go code:
@@ -240,8 +253,8 @@
   //     b1 := (cpv1 == *cpv2)
   //     b2 := (&cpv1 != cpv2)
   //     b3 := (&cpv1 == ***cpv2)
-
-  FcnTestHarness h("foo");
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -310,39 +323,39 @@
   }
 
   const char *exp = R"RAW_RESULT(
-  store %CPT.0* null, %CPT.0** %cpv1
-  store %CPT.0* null, %CPT.0** %cpv2
-  %cast.0 = bitcast %CPT.0** %cpv2 to %CPT.0*
-  store %CPT.0* %cast.0, %CPT.0** %cpv1
-  %cast.1 = bitcast %CPT.0** %cpv1 to %CPT.0*
-  store %CPT.0* %cast.1, %CPT.0** %cpv2
-  store i8 0, i8* %b1
-  store i8 0, i8* %b2
-  store i8 0, i8* %b3
-  %cpv1.ld.0 = load %CPT.0*, %CPT.0** %cpv1
-  %cast.2 = bitcast %CPT.0** %cpv2 to %CPT.0***
-  %cpv2.ld.0 = load %CPT.0**, %CPT.0*** %cast.2
-  %.ld.0 = load %CPT.0*, %CPT.0** %cpv2.ld.0
-  %icmp.0 = icmp eq %CPT.0* %cpv1.ld.0, %.ld.0
-  %zext.0 = zext i1 %icmp.0 to i8
-  store i8 %zext.0, i8* %b1
-  %cpv2.ld.1 = load %CPT.0*, %CPT.0** %cpv2
-  %cast.3 = bitcast %CPT.0* %cpv2.ld.1 to %CPT.0**
-  %icmp.1 = icmp eq %CPT.0** %cpv1, %cast.3
-  %zext.1 = zext i1 %icmp.1 to i8
-  store i8 %zext.1, i8* %b2
-  %cpv1.ld.1 = load %CPT.0*, %CPT.0** %cpv1
-  %cast.4 = bitcast %CPT.0** %cpv2 to %CPT.0***
-  %cpv2.ld.2 = load %CPT.0**, %CPT.0*** %cast.4
-  %cast.5 = bitcast %CPT.0** %cpv2.ld.2 to %CPT.0***
-  %deref.ld.0 = load %CPT.0**, %CPT.0*** %cast.5
-  %cast.6 = bitcast %CPT.0** %deref.ld.0 to %CPT.0***
-  %deref.ld.1 = load %CPT.0**, %CPT.0*** %cast.6
-  %.ld.1 = load %CPT.0*, %CPT.0** %deref.ld.1
-  %icmp.2 = icmp eq %CPT.0* %cpv1.ld.1, %.ld.1
-  %zext.2 = zext i1 %icmp.2 to i8
-  store i8 %zext.2, i8* %b3
-    )RAW_RESULT";
+    store %CPT.0* null, %CPT.0** %cpv1
+    store %CPT.0* null, %CPT.0** %cpv2
+    %cast.0 = bitcast %CPT.0** %cpv2 to %CPT.0*
+    store %CPT.0* %cast.0, %CPT.0** %cpv1
+    %cast.1 = bitcast %CPT.0** %cpv1 to %CPT.0*
+    store %CPT.0* %cast.1, %CPT.0** %cpv2
+    store i8 0, i8* %b1
+    store i8 0, i8* %b2
+    store i8 0, i8* %b3
+    %cpv1.ld.0 = load %CPT.0*, %CPT.0** %cpv1
+    %cast.2 = bitcast %CPT.0** %cpv2 to %CPT.0***
+    %cpv2.ld.0 = load %CPT.0**, %CPT.0*** %cast.2
+    %.ld.0 = load %CPT.0*, %CPT.0** %cpv2.ld.0
+    %icmp.0 = icmp eq %CPT.0* %cpv1.ld.0, %.ld.0
+    %zext.0 = zext i1 %icmp.0 to i8
+    store i8 %zext.0, i8* %b1
+    %cpv2.ld.1 = load %CPT.0*, %CPT.0** %cpv2
+    %cast.3 = bitcast %CPT.0* %cpv2.ld.1 to %CPT.0**
+    %icmp.1 = icmp eq %CPT.0** %cpv1, %cast.3
+    %zext.1 = zext i1 %icmp.1 to i8
+    store i8 %zext.1, i8* %b2
+    %cpv1.ld.1 = load %CPT.0*, %CPT.0** %cpv1
+    %cast.4 = bitcast %CPT.0** %cpv2 to %CPT.0***
+    %cpv2.ld.2 = load %CPT.0**, %CPT.0*** %cast.4
+    %cast.5 = bitcast %CPT.0** %cpv2.ld.2 to %CPT.0***
+    %deref.ld.0 = load %CPT.0**, %CPT.0*** %cast.5
+    %cast.6 = bitcast %CPT.0** %deref.ld.0 to %CPT.0***
+    %deref.ld.1 = load %CPT.0**, %CPT.0*** %cast.6
+    %.ld.1 = load %CPT.0*, %CPT.0** %deref.ld.1
+    %icmp.2 = icmp eq %CPT.0* %cpv1.ld.1, %.ld.1
+    %zext.2 = zext i1 %icmp.2 to i8
+    store i8 %zext.2, i8* %b3
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -351,7 +364,7 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendPointerExprTests, CircularPointerExpressions2) {
+TEST_P(BackendPointerExprTests, CircularPointerExpressions2) {
 
   // More tests for circular pointers, this time
   // with multiple levels. Go code:
@@ -364,8 +377,8 @@
   //     x = &y
   //     y = &x
   //     b1 := (x == *y)
-
-  FcnTestHarness h("foo");
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -411,19 +424,19 @@
   }
 
   const char *exp = R"RAW_RESULT(
-  store %CPT.0* null, %CPT.0** %x
-  store %CPT.0** null, %CPT.0*** %y
-  %cast.0 = bitcast %CPT.0*** %y to %CPT.0*
-  store %CPT.0* %cast.0, %CPT.0** %x
-  store %CPT.0** %x, %CPT.0*** %y
-  store i8 0, i8* %b1
-  %x.ld.0 = load %CPT.0*, %CPT.0** %x
-  %y.ld.0 = load %CPT.0**, %CPT.0*** %y
-  %.ld.0 = load %CPT.0*, %CPT.0** %y.ld.0
-  %icmp.0 = icmp eq %CPT.0* %x.ld.0, %.ld.0
-  %zext.0 = zext i1 %icmp.0 to i8
-  store i8 %zext.0, i8* %b1
-    )RAW_RESULT";
+    store %CPT.0* null, %CPT.0** %x
+    store %CPT.0** null, %CPT.0*** %y
+    %cast.0 = bitcast %CPT.0*** %y to %CPT.0*
+    store %CPT.0* %cast.0, %CPT.0** %x
+    store %CPT.0** %x, %CPT.0*** %y
+    store i8 0, i8* %b1
+    %x.ld.0 = load %CPT.0*, %CPT.0** %x
+    %y.ld.0 = load %CPT.0**, %CPT.0*** %y
+    %.ld.0 = load %CPT.0*, %CPT.0** %y.ld.0
+    %icmp.0 = icmp eq %CPT.0* %x.ld.0, %.ld.0
+    %zext.0 = zext i1 %icmp.0 to i8
+    store i8 %zext.0, i8* %b1
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -432,9 +445,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendPointerExprTests, CreatePointerOffsetExprs) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendPointerExprTests, CreatePointerOffsetExprs) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -466,14 +479,14 @@
   }
 
   const char *exp = R"RAW_RESULT(
-  %param3.ld.0 = load i64*, i64** %param3.addr
-  %ptroff.0 = getelementptr i64, i64* %param3.ld.0, i32 5
-  store i64 9, i64* %ptroff.0
-  %param3.ld.1 = load i64*, i64** %param3.addr
-  %ptroff.1 = getelementptr i64, i64* %param3.ld.1, i32 7
-  %.ptroff.ld.0 = load i64, i64* %ptroff.1
-  %trunc.0 = trunc i64 %.ptroff.ld.0 to i32
-  store i32 %trunc.0, i32* %param1.addr
+    %param3.ld.0 = load i64*, i64** %param3.addr
+    %ptroff.0 = getelementptr i64, i64* %param3.ld.0, i32 5
+    store i64 9, i64* %ptroff.0
+    %param3.ld.1 = load i64*, i64** %param3.addr
+    %ptroff.1 = getelementptr i64, i64* %param3.ld.1, i32 7
+    %.ptroff.ld.0 = load i64, i64* %ptroff.1
+    %trunc.0 = trunc i64 %.ptroff.ld.0 to i32
+    store i32 %trunc.0, i32* %param1.addr
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -483,9 +496,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendPointerExprTests, TestAddrDerefFold) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendPointerExprTests, TestAddrDerefFold) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -505,8 +518,8 @@
   h.mkAssign(vexl, ad3);
 
   const char *exp = R"RAW_RESULT(
-  store i64 0, i64* %x
-  store i64* %x, i64** %param3.addr
+    store i64 0, i64* %x
+    store i64* %x, i64** %param3.addr
   )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
@@ -516,9 +529,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendPointerExprTests, TestDerefPointerConstantLHS)
-{
-  FcnTestHarness h("foo");
+TEST_P(BackendPointerExprTests, TestDerefPointerConstantLHS) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -570,16 +583,15 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendPointerExprTests, TestCircularFunctionTypes)
-{
+TEST_P(BackendPointerExprTests, TestCircularFunctionTypes) {
   // Make sure we can handle circular function types, especially
   // those in which the cycle extends across multiple types. Example:
   //
   // type gf1 func(int, int, gf1, gf2) int
   // type gf2 func(int, int, gf2, gf1) int
   //
-
-  FcnTestHarness h("foo");
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Location loc;
 
@@ -613,10 +625,10 @@
   h.mkLocal("y", pbefty2);
 
   const char *exp = R"RAW_RESULT(
-   store i64 (i8*, i64, i64, %CFT.0*, %CFT.1*)* null, i64 (i8*, i64, i64, %CFT.0*, %CFT.1*)** %x
-   store i64 (i8*, i64, i64, %CFT.1*, %CFT.0*)* null, i64 (i8*, i64, i64, %CFT.1*, %CFT.0*)** %y
+    store i64 (i8*, i64, i64, %CFT.0*, %CFT.1*)* null, i64 (i8*, i64, i64, %CFT.0*, %CFT.1*)** %x
+    store i64 (i8*, i64, i64, %CFT.1*, %CFT.0*)* null, i64 (i8*, i64, i64, %CFT.1*, %CFT.0*)** %y
 
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -625,4 +637,4 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendStmtTests.cpp b/unittests/BackendCore/BackendStmtTests.cpp
index 36ff99c..0b07dcb 100644
--- a/unittests/BackendCore/BackendStmtTests.cpp
+++ b/unittests/BackendCore/BackendStmtTests.cpp
@@ -15,9 +15,20 @@
 
 namespace {
 
-TEST(BackendStmtTests, TestInitStmt) {
+class BackendStmtTests : public testing::TestWithParam<llvm::CallingConv::ID> {
+};
 
-  FcnTestHarness h("foo");
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendStmtTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendStmtTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendStmtTests, TestInitStmt) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -43,8 +54,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendStmtTests, TestAssignmentStmt) {
-  FcnTestHarness h("foo");
+TEST_P(BackendStmtTests, TestAssignmentStmt) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -73,7 +85,7 @@
       store i64 0, i64* %loc2
       %loc1.ld.0 = load i64, i64* %loc1
       store i64 %loc1.ld.0, i64* %loc2
-   )RAW_RESULT";
+  )RAW_RESULT";
   bool isOK = h.expectBlock(exp);
   EXPECT_TRUE(isOK && "Block does not have expected contents");
 
@@ -89,9 +101,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendStmtTests, TestReturnStmt) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendStmtTests, TestReturnStmt) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -104,9 +116,9 @@
   Bstatement *ret = h.mkReturn(ve1);
 
   const char *exp = R"RAW_RESULT(
-     %loc1.ld.0 = load i64, i64* %loc1
-     ret i64 %loc1.ld.0
-   )RAW_RESULT";
+    %loc1.ld.0 = load i64, i64* %loc1
+    ret i64 %loc1.ld.0
+  )RAW_RESULT";
   std::string reason;
   bool equal = difftokens(exp, repr(ret), reason);
   EXPECT_EQ("pass", equal ? "pass" : reason);
@@ -121,11 +133,11 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendStmtTests, TestReturnStmt2) {
+TEST_P(BackendStmtTests, TestReturnStmt2) {
   // Test that dead code after the return statement is handled
   // correctly.
-
-  FcnTestHarness h("foo");
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -167,16 +179,17 @@
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-TEST(BackendStmtTests, TestLabelGotoStmts) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendStmtTests, TestLabelGotoStmts) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
   // loc1 = 10
   Location loc;
   Btype *bi64t = be->integer_type(false, 64);
-  Bvariable *loc1 = h.mkLocal("loc1", bi64t, mkInt64Const(be, 10));
+  Bvariable *loc1 = h.mkLocal("loc1", bi64t,
+                              mkInt64Const(be, 10));
 
   // goto labeln
   Blabel *lab1 = be->label(func, "foolab", loc);
@@ -195,9 +208,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendStmtTests, TestLabelAddressExpression) {
-
-  FcnTestHarness h;
+TEST_P(BackendStmtTests, TestLabelAddressExpression) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty);
@@ -237,7 +250,7 @@
       store i8 0, i8* %loc1
       ret void
     }
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
@@ -268,8 +281,9 @@
   return ifst;
 }
 
-TEST(BackendStmtTests, TestIfStmt) {
-  FcnTestHarness h("foo");
+TEST_P(BackendStmtTests, TestIfStmt) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -325,7 +339,7 @@
       store i64 987, i64* %loc1
       br label %fallthrough.1
     }
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
@@ -385,7 +399,7 @@
   std::vector<std::vector<Bexpression*> > cases = {
     { mkInt64Const(be, 1), mkInt64Const(be, 2) },
     { mkInt64Const(be, 3), mkInt64Const(be, 4) },
-    { mkInt64Const(be, 5)},
+    { mkInt64Const(be, 5) },
   };
   cases.push_back(std::vector<Bexpression*>()); // default
 
@@ -398,8 +412,9 @@
   h.addStmt(labdef);
 }
 
-TEST(BackendStmtTests, TestSwitchStmt) {
-  FcnTestHarness h("foo");
+TEST_P(BackendStmtTests, TestSwitchStmt) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -413,73 +428,74 @@
 
   // verify
   const char *exp = R"RAW_RESULT(
-   define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
-   entry:
-     %param1.addr = alloca i32
-     %param2.addr = alloca i32
-     %param3.addr = alloca i64*
-     %loc1 = alloca i64
-     %tmpv.0 = alloca i64
-     store i32 %param1, i32* %param1.addr
-     store i32 %param2, i32* %param2.addr
-     store i64* %param3, i64** %param3.addr
-     store i64 0, i64* %loc1
-     %loc1.ld.4 = load i64, i64* %loc1
-     switch i64 %loc1.ld.4, label %default.0 [
-       i64 1, label %case.0
-       i64 2, label %case.0
-       i64 3, label %case.1
-       i64 4, label %case.1
-       i64 5, label %case.2
-     ]
+    define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
+    entry:
+      %param1.addr = alloca i32
+      %param2.addr = alloca i32
+      %param3.addr = alloca i64*
+      %loc1 = alloca i64
+      %tmpv.0 = alloca i64
+      store i32 %param1, i32* %param1.addr
+      store i32 %param2, i32* %param2.addr
+      store i64* %param3, i64** %param3.addr
+      store i64 0, i64* %loc1
+      %loc1.ld.4 = load i64, i64* %loc1
+      switch i64 %loc1.ld.4, label %default.0 [
+        i64 1, label %case.0
+        i64 2, label %case.0
+        i64 3, label %case.1
+        i64 4, label %case.1
+        i64 5, label %case.2
+      ]
 
-   case.0:                                           ; preds = %entry, %entry
-     %loc1.ld.0 = load i64, i64* %loc1
-     %div.0 = sdiv i64 %loc1.ld.0, 123
-     store i64 %div.0, i64* %loc1
-     br label %label.0
+    case.0:                                           ; preds = %entry, %entry
+      %loc1.ld.0 = load i64, i64* %loc1
+      %div.0 = sdiv i64 %loc1.ld.0, 123
+      store i64 %div.0, i64* %loc1
+      br label %label.0
 
-   case.1:                                           ; preds = %entry, %entry
-     %loc1.ld.1 = load i64, i64* %loc1
-     %icmp.0 = icmp sle i64 %loc1.ld.1, 987
-     %zext.0 = zext i1 %icmp.0 to i8
-     %trunc.0 = trunc i8 %zext.0 to i1
-     br i1 %trunc.0, label %then.0, label %else.0
+    case.1:                                           ; preds = %entry, %entry
+      %loc1.ld.1 = load i64, i64* %loc1
+      %icmp.0 = icmp sle i64 %loc1.ld.1, 987
+      %zext.0 = zext i1 %icmp.0 to i8
+      %trunc.0 = trunc i8 %zext.0 to i1
+      br i1 %trunc.0, label %then.0, label %else.0
 
-   case.2:                                           ; preds = %entry, %fallthrough.0
-     br label %default.0
+    case.2:                                           ; preds = %entry, %fallthrough.0
+      br label %default.0
 
-   default.0:                                        ; preds = %entry, %case.2
-     store i64 456, i64* %loc1
-     br label %label.0
+    default.0:                                        ; preds = %entry, %case.2
+      store i64 456, i64* %loc1
+      br label %label.0
 
-   label.0:                                          ; preds = %default.0, %case.0
-     ret i64 10101
+    label.0:                                          ; preds = %default.0, %case.0
+      ret i64 10101
 
-   then.0:                                           ; preds = %case.1
-     %loc1.ld.3 = load i64, i64* %loc1
-     store i64 %loc1.ld.3, i64* %tmpv.0
-     br label %fallthrough.0
+    then.0:                                           ; preds = %case.1
+      %loc1.ld.3 = load i64, i64* %loc1
+      store i64 %loc1.ld.3, i64* %tmpv.0
+      br label %fallthrough.0
 
-   fallthrough.0:                                    ; preds = %else.0, %then.0
-     %tmpv.0.ld.0 = load i64, i64* %tmpv.0
-     store i64 %tmpv.0.ld.0, i64* %loc1
-     br label %case.2
+    fallthrough.0:                                    ; preds = %else.0, %then.0
+      %tmpv.0.ld.0 = load i64, i64* %tmpv.0
+      store i64 %tmpv.0.ld.0, i64* %loc1
+      br label %case.2
 
-   else.0:                                           ; preds = %case.1
-     %loc1.ld.2 = load i64, i64* %loc1
-     %mul.0 = mul i64 987, %loc1.ld.2
-     store i64 %mul.0, i64* %tmpv.0
-     br label %fallthrough.0
-   }
+    else.0:                                           ; preds = %case.1
+      %loc1.ld.2 = load i64, i64* %loc1
+      %mul.0 = mul i64 987, %loc1.ld.2
+      store i64 %mul.0, i64* %tmpv.0
+      br label %fallthrough.0
+    }
   )RAW_RESULT";
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-TEST(BackendStmtTests, TestStaticallyUnreachableStmts) {
-  FcnTestHarness h("foo");
+TEST_P(BackendStmtTests, TestStaticallyUnreachableStmts) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   // This test is designed to insure that there are no crashes,
@@ -519,7 +535,6 @@
   Bfunction *bdefretfcn = be->function(befty, "deferreturn", "deferreturn",
                                        fflags, h.newloc());
 
-
   // Materialize call to deferreturn
   Bexpression *retfn = be->function_code_expression(bdefretfcn, h.newloc());
   std::vector<Bexpression *> args1;
@@ -546,8 +561,9 @@
   return defer;
 }
 
-TEST(BackendStmtTests, TestDeferStmt) {
-  FcnTestHarness h;
+TEST_P(BackendStmtTests, TestDeferStmt) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty);
@@ -561,36 +577,37 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 
   const char *exp = R"RAW_RESULT(
-define void @foo(i8* nest %nest.0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
-entry:
-  %x = alloca i8
-  store i8 0, i8* %x
-  br label %finish.0
+    define void @foo(i8* nest %nest.0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
+    entry:
+      %x = alloca i8
+      store i8 0, i8* %x
+      br label %finish.0
 
-pad.0:                                            ; preds = %finish.0
-  %ex.0 = landingpad { i8*, i32 }
-          catch i8* null
-  br label %catch.0
+    pad.0:                                            ; preds = %finish.0
+      %ex.0 = landingpad { i8*, i32 }
+              catch i8* null
+      br label %catch.0
 
-catch.0:                                          ; preds = %pad.0
-  call void @checkdefer(i8* nest undef, i8* %x)
-  br label %finish.0
+    catch.0:                                          ; preds = %pad.0
+      call void @checkdefer(i8* nest undef, i8* %x)
+      br label %finish.0
 
-finish.0:                                         ; preds = %catch.0, %entry
-  invoke void @deferreturn(i8* nest undef, i8* %x)
-          to label %cont.0 unwind label %pad.0
+    finish.0:                                         ; preds = %catch.0, %entry
+      invoke void @deferreturn(i8* nest undef, i8* %x)
+              to label %cont.0 unwind label %pad.0
 
-cont.0:                                           ; preds = %finish.0
-  ret void
-}
-   )RAW_RESULT";
+    cont.0:                                           ; preds = %finish.0
+      ret void
+    }
+  )RAW_RESULT";
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-TEST(BackendStmtTests, TestExceptionHandlingStmt) {
-  FcnTestHarness h;
+TEST_P(BackendStmtTests, TestExceptionHandlingStmt) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("baz", befty);
@@ -611,24 +628,22 @@
   const char *fnames[] = { "plark", "plix" };
   Bfunction *fcns[4];
   Bexpression *calls[5];
-  for (unsigned ii = 0; ii < 2; ++ii)  {
+  for (unsigned ii = 0; ii < 2; ++ii) {
     fcns[ii] = be->function(befty, fnames[ii], fnames[ii], fflags, h.newloc());
     Bexpression *pfn = be->function_code_expression(fcns[ii], h.newloc());
     std::vector<Bexpression *> args;
-    calls[ii] = be->call_expression(func, pfn, args,
-                                    nullptr, h.newloc());
+    calls[ii] = be->call_expression(func, pfn, args, nullptr, h.newloc());
   }
   fcns[2] = be->function(befty2, "id", "id", fflags, h.newloc());
   Bexpression *idfn = be->function_code_expression(fcns[2], h.newloc());
   std::vector<Bexpression *> iargs;
   iargs.push_back(mkInt64Const(be, 99));
-  calls[2] = be->call_expression(func, idfn, iargs,
-                                 nullptr, h.newloc());
+  calls[2] = be->call_expression(func, idfn, iargs, nullptr, h.newloc());
   unsigned fflags2 = (Backend::function_is_visible |
                       Backend::function_does_not_return |
                       Backend::function_is_declaration);
   fcns[3] = be->function(beftynr, "noret", "noret", fflags2, h.newloc());
-  for (unsigned ii = 0; ii < 2; ++ii)  {
+  for (unsigned ii = 0; ii < 2; ++ii) {
     Bexpression *nrfn = be->function_code_expression(fcns[3], h.newloc());
     std::vector<Bexpression *> noargs;
     calls[3+ii] = be->call_expression(func, nrfn, noargs,
@@ -641,8 +656,7 @@
   // if false { y = noret(); y = noret() }
   // x = 123
   Bexpression *ve1 = be->var_expression(loc1, h.newloc());
-  Bstatement *as1 =
-      be->assignment_statement(func, ve1, calls[2], h.newloc());
+  Bstatement *as1 = be->assignment_statement(func, ve1, calls[2], h.newloc());
   Bblock *bb1 = mkBlockFromStmt(be, func, as1);
   addStmtToBlock(be, bb1, h.mkExprStmt(calls[0], FcnTestHarness::NoAppend));
   Bstatement *nrcs = h.mkExprStmt(calls[3], FcnTestHarness::NoAppend);
@@ -676,104 +690,104 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 
   const char *exp = R"RAW_RESULT(
-define void @baz(i8* nest %nest.0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
-entry:
-  %ehtmp.0 = alloca { i8*, i32 }
-  %x = alloca i64
-  %y = alloca i8
-  %sret.actual.0 = alloca { i8, i8 }
-  %sret.actual.1 = alloca { i8, i8 }
-  %finvar.0 = alloca i8
-  store i64 0, i64* %x
-  store i8 0, i8* %y
-  %call.0 = invoke i64 @id(i8* nest undef, i64 99)
-          to label %cont.1 unwind label %pad.1
+    define void @baz(i8* nest %nest.0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
+    entry:
+      %ehtmp.0 = alloca { i8*, i32 }
+      %x = alloca i64
+      %y = alloca i8
+      %sret.actual.0 = alloca { i8, i8 }
+      %sret.actual.1 = alloca { i8, i8 }
+      %finvar.0 = alloca i8
+      store i64 0, i64* %x
+      store i8 0, i8* %y
+      %call.0 = invoke i64 @id(i8* nest undef, i64 99)
+              to label %cont.1 unwind label %pad.1
 
-finok.0:                                          ; preds = %cont.4
-  store i8 1, i8* %finvar.0
-  br label %finally.0
+    finok.0:                                          ; preds = %cont.4
+      store i8 1, i8* %finvar.0
+      br label %finally.0
 
-finally.0:                                        ; preds = %catchpad.0, %finok.0
-  br label %finish.0
+    finally.0:                                        ; preds = %catchpad.0, %finok.0
+      br label %finish.0
 
-pad.0:                                            ; preds = %fallthrough.0, %finish.0
-  %ex.0 = landingpad { i8*, i32 }
-          catch i8* null
-  br label %catch.0
+    pad.0:                                            ; preds = %fallthrough.0, %finish.0
+      %ex.0 = landingpad { i8*, i32 }
+              catch i8* null
+      br label %catch.0
 
-catch.0:                                          ; preds = %pad.0
-  call void @checkdefer(i8* nest undef, i8* %y)
-  br label %finish.0
+    catch.0:                                          ; preds = %pad.0
+      call void @checkdefer(i8* nest undef, i8* %y)
+      br label %finish.0
 
-finish.0:                                         ; preds = %catch.0, %finally.0
-  invoke void @deferreturn(i8* nest undef, i8* %y)
-          to label %cont.0 unwind label %pad.0
+    finish.0:                                         ; preds = %catch.0, %finally.0
+      invoke void @deferreturn(i8* nest undef, i8* %y)
+              to label %cont.0 unwind label %pad.0
 
-cont.0:                                           ; preds = %fallthrough.0, %finish.0
-  %fload.0 = load i8, i8* %finvar.0
-  %icmp.0 = icmp eq i8 %fload.0, 1
-  br i1 %icmp.0, label %finret.0, label %finres.0
+    cont.0:                                           ; preds = %fallthrough.0, %finish.0
+      %fload.0 = load i8, i8* %finvar.0
+      %icmp.0 = icmp eq i8 %fload.0, 1
+      br i1 %icmp.0, label %finret.0, label %finres.0
 
-pad.1:                                            ; preds = %then.0, %cont.1, %entry
-  %ex.1 = landingpad { i8*, i32 }
-          catch i8* null
-  br label %catch.1
+    pad.1:                                            ; preds = %then.0, %cont.1, %entry
+      %ex.1 = landingpad { i8*, i32 }
+              catch i8* null
+      br label %catch.1
 
-catch.1:                                          ; preds = %pad.1
-  invoke void @plix(i8* nest undef)
-          to label %cont.4 unwind label %catchpad.0
+    catch.1:                                          ; preds = %pad.1
+      invoke void @plix(i8* nest undef)
+              to label %cont.4 unwind label %catchpad.0
 
-catchpad.0:                                       ; preds = %catch.1
-  %ex2.0 = landingpad { i8*, i32 }
-          cleanup
-  store { i8*, i32 } %ex2.0, { i8*, i32 }* %ehtmp.0
-  store i8 0, i8* %finvar.0
-  br label %finally.0
+    catchpad.0:                                       ; preds = %catch.1
+      %ex2.0 = landingpad { i8*, i32 }
+              cleanup
+      store { i8*, i32 } %ex2.0, { i8*, i32 }* %ehtmp.0
+      store i8 0, i8* %finvar.0
+      br label %finally.0
 
-cont.1:                                           ; preds = %entry
-  store i64 %call.0, i64* %x
-  invoke void @plark(i8* nest undef)
-          to label %cont.2 unwind label %pad.1
+    cont.1:                                           ; preds = %entry
+      store i64 %call.0, i64* %x
+      invoke void @plark(i8* nest undef)
+              to label %cont.2 unwind label %pad.1
 
-cont.2:                                           ; preds = %cont.1
-  br i1 false, label %then.0, label %else.0
+    cont.2:                                           ; preds = %cont.1
+      br i1 false, label %then.0, label %else.0
 
-then.0:                                           ; preds = %cont.2
-  %call.1 = invoke i16 @noret(i8* nest undef)
-          to label %cont.3 unwind label %pad.1
+    then.0:                                           ; preds = %cont.2
+      %call.1 = invoke i16 @noret(i8* nest undef)
+              to label %cont.3 unwind label %pad.1
 
-fallthrough.0:                                    ; preds = %else.0
-  store i64 123, i64* %x
-  store i8 1, i8* %finvar.0
-  invoke void @deferreturn(i8* nest undef, i8* %y)
-          to label %cont.0 unwind label %pad.0
+    fallthrough.0:                                    ; preds = %else.0
+      store i64 123, i64* %x
+      store i8 1, i8* %finvar.0
+      invoke void @deferreturn(i8* nest undef, i8* %y)
+              to label %cont.0 unwind label %pad.0
 
-else.0:                                           ; preds = %cont.2
-  br label %fallthrough.0
+    else.0:                                           ; preds = %cont.2
+      br label %fallthrough.0
 
-cont.3:                                           ; preds = %then.0
-  unreachable
+    cont.3:                                           ; preds = %then.0
+      unreachable
 
-cont.4:                                           ; preds = %catch.1
-  br label %finok.0
+    cont.4:                                           ; preds = %catch.1
+      br label %finok.0
 
-finres.0:                                         ; preds = %cont.0
-  %excv.0 = load { i8*, i32 }, { i8*, i32 }* %ehtmp.0
-  resume { i8*, i32 } %excv.0
+    finres.0:                                         ; preds = %cont.0
+      %excv.0 = load { i8*, i32 }, { i8*, i32 }* %ehtmp.0
+      resume { i8*, i32 } %excv.0
 
-finret.0:                                         ; preds = %cont.0
-  ret void
-}
-   )RAW_RESULT";
+    finret.0:                                         ; preds = %cont.0
+      ret void
+    }
+  )RAW_RESULT";
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
 static Bstatement *mkMemReturn(Llvm_backend *be,
-                                 Bfunction *func,
-                                 Bvariable *rtmp,
-                                 Bexpression *val)
+                               Bfunction *func,
+                               Bvariable *rtmp,
+                               Bexpression *val)
 {
   // Store value to tmp
   Location loc;
@@ -790,14 +804,15 @@
   return be->block_statement(block);
 }
 
-TEST(BackendStmtTests, TestExceptionHandlingStmtWithReturns) {
-  FcnTestHarness h;
+TEST_P(BackendStmtTests, TestExceptionHandlingStmtWithReturns) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   Btype *bi64t = be->integer_type(false, 64);
   BFunctionType *befty = mkFuncTyp(be,
-                                    L_PARM, bi64t,
-                                    L_RES, bi64t,
-                                    L_END);
+                                   L_PARM, bi64t,
+                                   L_RES, bi64t,
+                                   L_END);
   Bfunction *func = h.mkFunction("baz", befty);
   Bvariable *rtmp = h.mkLocal("ret", bi64t);
 
@@ -823,9 +838,9 @@
     Bexpression *splcall = be->call_expression(func, splfn, iargs,
                                                nullptr, h.newloc());
     Bexpression *eq = be->binary_expression(OPERATOR_EQEQ,
-                                          splcall,
-                                          mkInt64Const(be, 88),
-                                          h.loc());
+                                            splcall,
+                                            mkInt64Const(be, 88),
+                                            h.loc());
     Bvariable *p0 = func->getNthParamVar(0);
     Bexpression *ve1 = be->var_expression(p0, h.newloc());
 
@@ -864,94 +879,94 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 
   const char *exp = R"RAW_RESULT(
-define i64 @baz(i8* nest %nest.0, i64 %p0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
-entry:
-  %ehtmp.0 = alloca { i8*, i32 }
-  %p0.addr = alloca i64
-  %ret = alloca i64
-  %x = alloca i8
-  %finvar.0 = alloca i8
-  store i64 %p0, i64* %p0.addr
-  store i64 0, i64* %ret
-  store i8 0, i8* %x
-  %call.0 = invoke i64 @splat(i8* nest undef, i64 99)
-          to label %cont.1 unwind label %pad.1
+    define i64 @baz(i8* nest %nest.0, i64 %p0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
+    entry:
+      %ehtmp.0 = alloca { i8*, i32 }
+      %p0.addr = alloca i64
+      %ret = alloca i64
+      %x = alloca i8
+      %finvar.0 = alloca i8
+      store i64 %p0, i64* %p0.addr
+      store i64 0, i64* %ret
+      store i8 0, i8* %x
+      %call.0 = invoke i64 @splat(i8* nest undef, i64 99)
+              to label %cont.1 unwind label %pad.1
 
-finok.0:                                          ; preds = %cont.2
-  store i8 1, i8* %finvar.0
-  br label %finally.0
+    finok.0:                                          ; preds = %cont.2
+      store i8 1, i8* %finvar.0
+      br label %finally.0
 
-finally.0:                                        ; preds = %catchpad.0, %finok.0
-  br label %finish.0
+    finally.0:                                        ; preds = %catchpad.0, %finok.0
+      br label %finish.0
 
-pad.0:                                            ; preds = %else.0, %then.0, %finish.0
-  %ex.0 = landingpad { i8*, i32 }
-          catch i8* null
-  br label %catch.0
+    pad.0:                                            ; preds = %else.0, %then.0, %finish.0
+      %ex.0 = landingpad { i8*, i32 }
+              catch i8* null
+      br label %catch.0
 
-catch.0:                                          ; preds = %pad.0
-  call void @checkdefer(i8* nest undef, i8* %x)
-  br label %finish.0
+    catch.0:                                          ; preds = %pad.0
+      call void @checkdefer(i8* nest undef, i8* %x)
+      br label %finish.0
 
-finish.0:                                         ; preds = %catch.0, %finally.0
-  invoke void @deferreturn(i8* nest undef, i8* %x)
-          to label %cont.0 unwind label %pad.0
+    finish.0:                                         ; preds = %catch.0, %finally.0
+      invoke void @deferreturn(i8* nest undef, i8* %x)
+              to label %cont.0 unwind label %pad.0
 
-cont.0:                                           ; preds = %else.0, %then.0, %finish.0
-  %fload.0 = load i8, i8* %finvar.0
-  %icmp.1 = icmp eq i8 %fload.0, 1
-  br i1 %icmp.1, label %finret.0, label %finres.0
+    cont.0:                                           ; preds = %else.0, %then.0, %finish.0
+      %fload.0 = load i8, i8* %finvar.0
+      %icmp.1 = icmp eq i8 %fload.0, 1
+      br i1 %icmp.1, label %finret.0, label %finres.0
 
-pad.1:                                            ; preds = %entry
-  %ex.1 = landingpad { i8*, i32 }
-          catch i8* null
-  br label %catch.1
+    pad.1:                                            ; preds = %entry
+      %ex.1 = landingpad { i8*, i32 }
+              catch i8* null
+      br label %catch.1
 
-catch.1:                                          ; preds = %pad.1
-  %call.1 = invoke i64 @splat(i8* nest undef, i64 13)
-          to label %cont.2 unwind label %catchpad.0
+    catch.1:                                          ; preds = %pad.1
+      %call.1 = invoke i64 @splat(i8* nest undef, i64 13)
+              to label %cont.2 unwind label %catchpad.0
 
-catchpad.0:                                       ; preds = %catch.1
-  %ex2.0 = landingpad { i8*, i32 }
-          cleanup
-  store { i8*, i32 } %ex2.0, { i8*, i32 }* %ehtmp.0
-  store i8 0, i8* %finvar.0
-  br label %finally.0
+    catchpad.0:                                       ; preds = %catch.1
+      %ex2.0 = landingpad { i8*, i32 }
+              cleanup
+      store { i8*, i32 } %ex2.0, { i8*, i32 }* %ehtmp.0
+      store i8 0, i8* %finvar.0
+      br label %finally.0
 
-cont.1:                                           ; preds = %entry
-  %icmp.0 = icmp eq i64 %call.0, 88
-  %zext.0 = zext i1 %icmp.0 to i8
-  %trunc.0 = trunc i8 %zext.0 to i1
-  br i1 %trunc.0, label %then.0, label %else.0
+    cont.1:                                           ; preds = %entry
+      %icmp.0 = icmp eq i64 %call.0, 88
+      %zext.0 = zext i1 %icmp.0 to i8
+      %trunc.0 = trunc i8 %zext.0 to i1
+      br i1 %trunc.0, label %then.0, label %else.0
 
-then.0:                                           ; preds = %cont.1
-  store i64 22, i64* %ret
-  store i8 1, i8* %finvar.0
-  invoke void @deferreturn(i8* nest undef, i8* %x)
-          to label %cont.0 unwind label %pad.0
+    then.0:                                           ; preds = %cont.1
+      store i64 22, i64* %ret
+      store i8 1, i8* %finvar.0
+      invoke void @deferreturn(i8* nest undef, i8* %x)
+              to label %cont.0 unwind label %pad.0
 
-else.0:                                           ; preds = %cont.1
-  %p0.ld.0 = load i64, i64* %p0.addr
-  store i64 %p0.ld.0, i64* %ret
-  store i8 1, i8* %finvar.0
-  invoke void @deferreturn(i8* nest undef, i8* %x)
-          to label %cont.0 unwind label %pad.0
+    else.0:                                           ; preds = %cont.1
+      %p0.ld.0 = load i64, i64* %p0.addr
+      store i64 %p0.ld.0, i64* %ret
+      store i8 1, i8* %finvar.0
+      invoke void @deferreturn(i8* nest undef, i8* %x)
+              to label %cont.0 unwind label %pad.0
 
-cont.2:                                           ; preds = %catch.1
-  br label %finok.0
+    cont.2:                                           ; preds = %catch.1
+      br label %finok.0
 
-finres.0:                                         ; preds = %cont.0
-  %excv.0 = load { i8*, i32 }, { i8*, i32 }* %ehtmp.0
-  resume { i8*, i32 } %excv.0
+    finres.0:                                         ; preds = %cont.0
+      %excv.0 = load { i8*, i32 }, { i8*, i32 }* %ehtmp.0
+      resume { i8*, i32 } %excv.0
 
-finret.0:                                         ; preds = %cont.0
-  %ret.ld.1 = load i64, i64* %ret
-  ret i64 %ret.ld.1
-}
-   )RAW_RESULT";
+    finret.0:                                         ; preds = %cont.0
+      %ret.ld.1 = load i64, i64* %ret
+      ret i64 %ret.ld.1
+    }
+  )RAW_RESULT";
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Function does not have expected contents");
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendTreeIntegrity.cpp b/unittests/BackendCore/BackendTreeIntegrity.cpp
index 5beec52..35e931b 100644
--- a/unittests/BackendCore/BackendTreeIntegrity.cpp
+++ b/unittests/BackendCore/BackendTreeIntegrity.cpp
@@ -15,8 +15,20 @@
 
 namespace {
 
-TEST(BackendTreeIntegrity, CheckTreeIntegrity1) {
-  FcnTestHarness h("foo");
+class BackendTreeIntegrity
+    : public testing::TestWithParam<llvm::CallingConv::ID> {};
+
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendTreeIntegrity,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendTreeIntegrity::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendTreeIntegrity, CheckTreeIntegrity1) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
   Location loc;
@@ -60,11 +72,13 @@
   h.finish(PreserveDebugInfo);
 }
 
-TEST(BackendTreeIntegrity, CheckTreeIntegrity2) {
+TEST_P(BackendTreeIntegrity, CheckTreeIntegrity2) {
 
   // Add the same Expression to more than one statement
   LLVMContext C;
-  std::unique_ptr<Llvm_backend> be(new Llvm_backend(C, nullptr, nullptr, 0));
+  auto cc = GetParam();
+  std::unique_ptr<Llvm_backend> be(
+      new Llvm_backend(C, nullptr, nullptr, 0, cc));
   be->disableIntegrityChecks();
 
   Location loc;
@@ -81,8 +95,7 @@
   addStmtToBlock(be.get(), block, es2);
 
   TreeIntegCtl control(NoDumpPointers, ReportRepairableSharing, BatchMode);
-  std::pair<bool, std::string> result =
-      be->checkTreeIntegrity(block, control);
+  std::pair<bool, std::string> result = be->checkTreeIntegrity(block, control);
   EXPECT_FALSE(result.first);
   EXPECT_TRUE(containstokens(result.second, "expr has multiple parents"));
 
@@ -97,11 +110,13 @@
   be->function_set_body(func, block2);
 }
 
-TEST(BackendTreeIntegrity, CheckTreeIntegrity3) {
+TEST_P(BackendTreeIntegrity, CheckTreeIntegrity3) {
 
   // Same statement with more than one parent.
   LLVMContext C;
-  std::unique_ptr<Llvm_backend> be(new Llvm_backend(C, nullptr, nullptr, 0));
+  auto cc = GetParam();
+  std::unique_ptr<Llvm_backend> be(
+      new Llvm_backend(C, nullptr, nullptr, 0, cc));
   be->disableIntegrityChecks();
   Location loc;
   Bfunction *func = mkFunci32o64(be.get(), "foo");
@@ -113,8 +128,7 @@
   addStmtToBlock(be.get(), block, es);
 
   TreeIntegCtl control(NoDumpPointers, ReportRepairableSharing, BatchMode);
-  std::pair<bool, std::string> result =
-      be->checkTreeIntegrity(block, control);
+  std::pair<bool, std::string> result = be->checkTreeIntegrity(block, control);
   EXPECT_FALSE(result.first);
   EXPECT_TRUE(containstokens(result.second, "stmt has multiple parents"));
 
@@ -127,8 +141,9 @@
   be->function_set_body(func, block2);
 }
 
-TEST(BackendTreeIntegrity, CheckTreeIntegrityRepairableSubtree) {
-  FcnTestHarness h;
+TEST_P(BackendTreeIntegrity, CheckTreeIntegrityRepairableSubtree) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   Btype *bi32t = be->integer_type(false, 32);
   Btype *bpi32t = be->pointer_type(bi32t);
@@ -152,8 +167,7 @@
   // p0 == nil ? 1 : *p0
   Bexpression *vex2 = be->var_expression(p0v, loc);
   Bexpression *npe = be->nil_pointer_expression();
-  Bexpression *cmp =
-      be->binary_expression(OPERATOR_EQEQ, npe, vex2, loc);
+  Bexpression *cmp = be->binary_expression(OPERATOR_EQEQ, npe, vex2, loc);
   Bexpression *der2 = be->indirect_expression(bi32t, vex2, false, loc);
   Bexpression *const1 = mkInt32Const(be, 1);
   Bexpression *condex = be->conditional_expression(func, bi32t, cmp, const1,
@@ -178,11 +192,9 @@
   Bfunction *rtefcn = be->function(bfterr, rtename, rtename, fflags, loc);
 
   // p0 != nil ? *p0 + 3 : runtime_error(6)
-  Bexpression *cmp2 =
-      be->binary_expression(OPERATOR_NOTEQ, vex3, npe, loc);
+  Bexpression *cmp2 = be->binary_expression(OPERATOR_NOTEQ, vex3, npe, loc);
   Bexpression *der3 = be->indirect_expression(bi32t, vex3, false, loc);
-  Bexpression *add2 =
-      be->binary_expression(OPERATOR_PLUS, mkInt32Const(be, 3), der3, loc);
+  Bexpression *add2 = be->binary_expression(OPERATOR_PLUS, mkInt32Const(be, 3), der3, loc);
   Bexpression *const6 = mkInt32Const(be, 6);
   Bexpression *call3 = h.mkCallExpr(be, rtefcn, const6, nullptr);
   Bexpression *condex2 = be->conditional_expression(func, bi32t, cmp2, add2,
@@ -201,4 +213,4 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/BackendVarTests.cpp b/unittests/BackendCore/BackendVarTests.cpp
index 183a0ae..149cbc5 100644
--- a/unittests/BackendCore/BackendVarTests.cpp
+++ b/unittests/BackendCore/BackendVarTests.cpp
@@ -20,8 +20,19 @@
 
 namespace {
 
-TEST(BackendVarTests, MakeLocalVar) {
-  FcnTestHarness h("foo");
+class BackendVarTests : public testing::TestWithParam<llvm::CallingConv::ID> {};
+
+INSTANTIATE_TEST_CASE_P(
+    UnitTest, BackendVarTests,
+    testing::Values(llvm::CallingConv::X86_64_SysV),
+    [](const testing::TestParamInfo<BackendVarTests::ParamType> &info) {
+      std::string name = goBackendUnitTests::ccName(info.param);
+      return name;
+    });
+
+TEST_P(BackendVarTests, MakeLocalVar) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func1 = h.func();
   Bfunction *func2 = mkFunci32o64(be, "bar");
@@ -66,10 +77,10 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendVarTests, MakeParamVar) {
+TEST_P(BackendVarTests, MakeParamVar) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
   bool dontMakeParams = false;
   Bfunction *func = mkFunci32o64(be.get(), "foo", dontMakeParams);
 
@@ -99,10 +110,10 @@
   EXPECT_TRUE(p3 == be->error_variable());
 }
 
-TEST(BackendVarTests, MakeGlobalVar) {
+TEST_P(BackendVarTests, MakeGlobalVar) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   Btype *bi32t = be->integer_type(false, 32);
   Bvariable *g1 =
@@ -133,8 +144,9 @@
   EXPECT_TRUE(gerr == be->error_variable());
 }
 
-TEST(BackendVarTests, MakeTemporaryVar) {
-  FcnTestHarness h("foo");
+TEST_P(BackendVarTests, MakeTemporaryVar) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -159,8 +171,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendVarTests, MakeImmutableStruct) {
-  FcnTestHarness h("foo");
+TEST_P(BackendVarTests, MakeImmutableStruct) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   Btype *bi32t = be->integer_type(false, 32);
@@ -198,10 +211,10 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendVarTests, MakeImplicitVariable) {
+TEST_P(BackendVarTests, MakeImplicitVariable) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
 
   Btype *bi32t = be->integer_type(false, 32);
   Btype *bst = mkTwoFieldStruct(be.get(), bi32t, bi32t);
@@ -234,14 +247,13 @@
 
   // error case
   Bvariable *gerr =
-      be->implicit_variable("", "", be->error_type(), false, false,
-                            false, 0);
+      be->implicit_variable("", "", be->error_type(), false, false, false, 0);
   EXPECT_TRUE(gerr == be->error_variable());
 }
 
-TEST(BackendVarTests, MakeImmutableStructReference) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendVarTests, MakeImmutableStructReference) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   Location loc;
@@ -264,9 +276,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendVarTests, ImmutableStructSetInit) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendVarTests, ImmutableStructSetInit) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func = h.func();
 
@@ -297,7 +309,7 @@
   }
 
   Bvariable *ims2 = be->immutable_struct("xyz", "abc",
-                                        false, true, desct, loc);
+                                         false, true, desct, loc);
   be->immutable_struct_set_init(ims2, "", false, true,
                                 desct, loc, be->zero_expression(desct));
 
@@ -320,9 +332,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendVarTests, MakeImmutableStructReferenceWithSameName) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendVarTests, MakeImmutableStructReferenceWithSameName) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   Location loc;
@@ -338,8 +350,7 @@
       be->immutable_struct("name", "asmname", hidden, common, bst, loc);
   ASSERT_TRUE(ims != nullptr);
 
-  Bvariable *imsr =
-      be->immutable_struct_reference("name", "asmname", bst, loc);
+  Bvariable *imsr = be->immutable_struct_reference("name", "asmname", bst, loc);
   ASSERT_TRUE(imsr != nullptr);
   EXPECT_TRUE(isa<GlobalVariable>(imsr->value()));
   EXPECT_TRUE(imsr->value() == ims->value());
@@ -348,9 +359,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendVarTests, ImplicitVariableSetInit) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendVarTests, ImplicitVariableSetInit) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   Location loc;
@@ -374,8 +385,8 @@
                                  isHidden, isConst, isCommon, con1);
 
   const char *exp1 = R"RAW_RESULT(
-     @v1 = global { i32, i32 } { i32 101, i32 202 }, align 8
-    )RAW_RESULT";
+    @v1 = global { i32, i32 } { i32 101, i32 202 }, align 8
+  )RAW_RESULT";
 
   bool isOK1 = h.expectValue(ims1->value(), exp1);
   EXPECT_TRUE(isOK1 && "Value does not have expected contents");
@@ -383,15 +394,14 @@
   // Case 2: const, common, no init value.
   isConst = true;
   isCommon = true;
-  Bvariable *ims2 =
-      be->implicit_variable("second", "v2", bst,
-                            isHidden, isConst, isCommon, 8);
+  Bvariable *ims2 = be->implicit_variable("second", "v2", bst,
+                                          isHidden, isConst, isCommon, 8);
   be->implicit_variable_set_init(ims2, "x", bst,
                                  isHidden, isConst, isCommon, nullptr);
 
   const char *exp2 = R"RAW_RESULT(
     @v2 = weak constant { i32, i32 } zeroinitializer, comdat, align 8
-    )RAW_RESULT";
+  )RAW_RESULT";
 
   bool isOK2 = h.expectValue(ims2->value(), exp2);
   EXPECT_TRUE(isOK2 && "Value does not have expected contents");
@@ -407,10 +417,10 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendVarTests, GlobalVarSetInitToComposite) {
+TEST_P(BackendVarTests, GlobalVarSetInitToComposite) {
   LLVMContext C;
-
-  std::unique_ptr<Backend> be(go_get_backend(C));
+  auto cc = GetParam();
+  std::unique_ptr<Backend> be(go_get_backend(C, cc));
   Location loc;
 
   Btype *bt = be->bool_type();
@@ -433,9 +443,9 @@
   be->global_variable_set_init(g1, scon);
 }
 
-TEST(BackendVarTests, GlobalVarsWithSameName) {
-
-  FcnTestHarness h("foo");
+TEST_P(BackendVarTests, GlobalVarsWithSameName) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
 
   Location loc;
@@ -464,7 +474,7 @@
   EXPECT_TRUE(isa<GlobalVariable>(gv->value()));
   EXPECT_EQ(repr(gv->value()), "@x = global { i32 } zeroinitializer");
   EXPECT_EQ(repr(gvdecl->value()),
-      "i32* getelementptr inbounds ({ i32 }, { i32 }* @x, i32 0, i32 0)");
+            "i32* getelementptr inbounds ({ i32 }, { i32 }* @x, i32 0, i32 0)");
 
   // Create them in the other order: definition first,
   // then external declaration.
@@ -490,9 +500,9 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 }
 
-TEST(BackendVarTests, TestVarLifetimeInsertion) {
-
-  FcnTestHarness h;
+TEST_P(BackendVarTests, TestVarLifetimeInsertion) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty1 = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty1);
@@ -524,36 +534,36 @@
   EXPECT_FALSE(broken && "Module failed to verify.");
 
   const char *exp = R"RAW_RESULT(
-  define void @foo(i8* nest %nest.0) #0 {
-  entry:
-    %x = alloca i32
-    %y = alloca { i32, i32 }
-    %0 = bitcast i32* %x to i8*
-    call void @llvm.lifetime.start.p0i8(i64 4, i8* %0)
-    %1 = bitcast { i32, i32 }* %y to i8*
-    call void @llvm.lifetime.start.p0i8(i64 8, i8* %1)
-    store i32 0, i32* %x
-    %cast.0 = bitcast { i32, i32 }* %y to i8*
-    %cast.1 = bitcast { i32, i32 }* @const.0 to i8*
-    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 %cast.1, i64 8, i1 false)
-    %field.0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i32 0, i32 1
-    %y.field.ld.0 = load i32, i32* %field.0
-    store i32 %y.field.ld.0, i32* %x
-    %2 = bitcast i32* %x to i8*
-    call void @llvm.lifetime.end.p0i8(i64 4, i8* %2)
-    %3 = bitcast { i32, i32 }* %y to i8*
-    call void @llvm.lifetime.end.p0i8(i64 8, i8* %3)
-    ret void
-  }
-    )RAW_RESULT";
+    define void @foo(i8* nest %nest.0) #0 {
+    entry:
+      %x = alloca i32
+      %y = alloca { i32, i32 }
+      %0 = bitcast i32* %x to i8*
+      call void @llvm.lifetime.start.p0i8(i64 4, i8* %0)
+      %1 = bitcast { i32, i32 }* %y to i8*
+      call void @llvm.lifetime.start.p0i8(i64 8, i8* %1)
+      store i32 0, i32* %x
+      %cast.0 = bitcast { i32, i32 }* %y to i8*
+      %cast.1 = bitcast { i32, i32 }* @const.0 to i8*
+      call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 %cast.1, i64 8, i1 false)
+      %field.0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i32 0, i32 1
+      %y.field.ld.0 = load i32, i32* %field.0
+      store i32 %y.field.ld.0, i32* %x
+      %2 = bitcast i32* %x to i8*
+      call void @llvm.lifetime.end.p0i8(i64 4, i8* %2)
+      %3 = bitcast { i32, i32 }* %y to i8*
+      call void @llvm.lifetime.end.p0i8(i64 8, i8* %3)
+      ret void
+    }
+  )RAW_RESULT";
 
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Value does not have expected contents");
 }
 
-TEST(BackendVarTests, ZeroSizedGlobals) {
-
-  FcnTestHarness h;
+TEST_P(BackendVarTests, ZeroSizedGlobals) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc);
   Llvm_backend *be = h.be();
   BFunctionType *befty1 = mkFuncTyp(be, L_END);
   Bfunction *func = h.mkFunction("foo", befty1);
@@ -678,14 +688,14 @@
       %localemptyintar = alloca [0 x i32]
       ret void
     }
-    )RAW_RESULT";
+  )RAW_RESULT";
   bool isOK = h.expectValue(func->function(), exp);
   EXPECT_TRUE(isOK && "Value does not have expected contents");
-
 }
 
-TEST(BackendVarTests, MakeLocalWithDeclVar) {
-  FcnTestHarness h("foo");
+TEST_P(BackendVarTests, MakeLocalWithDeclVar) {
+  auto cc = GetParam();
+  FcnTestHarness h(cc, "foo");
   Llvm_backend *be = h.be();
   Bfunction *func1 = h.func();
 
@@ -728,4 +738,4 @@
   EXPECT_EQ(h.countInstancesInModuleDump(expected), 1u);
 }
 
-}
+} // namespace
diff --git a/unittests/BackendCore/TestUtils.cpp b/unittests/BackendCore/TestUtils.cpp
index 4f2c41e..1ac9bb1 100644
--- a/unittests/BackendCore/TestUtils.cpp
+++ b/unittests/BackendCore/TestUtils.cpp
@@ -12,6 +12,19 @@
 
 namespace goBackendUnitTests {
 
+std::string ccName(llvm::CallingConv::ID cc) {
+  assert(cc == llvm::CallingConv::X86_64_SysV ||
+         cc == llvm::CallingConv::ARM_AAPCS);
+  switch (cc) {
+  case llvm::CallingConv::X86_64_SysV:
+    return "X8664SysV";
+  case llvm::CallingConv::ARM_AAPCS:
+    return "ARMAAPCS";
+  default:
+    return "";
+  }
+}
+
 std::string repr(llvm::Value *val) {
   std::string res;
   llvm::raw_string_ostream os(res);
@@ -209,10 +222,9 @@
   Btype *bi64t = be->integer_type(false, 64);
   Btype *bi32t = be->integer_type(false, 32);
   Btype *bpi64t = be->pointer_type(bi64t);
-  Btype *befty =
-      mkFuncTyp(be,
-                L_PARM, bi32t, L_PARM, bi32t, L_PARM, bpi64t,
-                L_RES, bi64t, L_END);
+  Btype *befty = mkFuncTyp(be,
+                           L_PARM, bi32t, L_PARM, bi32t, L_PARM, bpi64t,
+                           L_RES, bi64t, L_END);
   unsigned fflags = (Backend::function_is_visible |
                      Backend::function_is_inlinable);
   Location loc;
@@ -372,9 +384,9 @@
   return trimsp(vis.result());
 }
 
-FcnTestHarness::FcnTestHarness(const char *fcnName)
+FcnTestHarness::FcnTestHarness(llvm::CallingConv::ID cconv, const char *fcnName)
     : context_()
-    , be_(new Llvm_backend(context_, nullptr, nullptr, 0))
+    , be_(new Llvm_backend(context_, nullptr, nullptr, 0, cconv))
     , func_(nullptr)
     , entryBlock_(nullptr)
     , curBlock_(nullptr)
@@ -513,9 +525,9 @@
 }
 
 Bstatement *FcnTestHarness::mkSwitch(Bexpression *swval,
-                       const std::vector<std::vector<Bexpression*> >& cases,
-                       const std::vector<Bstatement*>& statements,
-                                     AppendDisp disp)
+                       const std::vector<std::vector<Bexpression *>> &cases,
+                       const std::vector<Bstatement *> &statements,
+                       AppendDisp disp)
 {
   assert(func_);
   Bstatement *swst = be()->switch_statement(func_, swval,
@@ -525,7 +537,6 @@
   return swst;
 }
 
-
 void FcnTestHarness::addStmt(Bstatement *stmt)
 {
   assert(func_);
@@ -562,8 +573,8 @@
 
 bool FcnTestHarness::expectStmt(Bstatement *st, const std::string &expected)
 {
- std::string reason;
- std::string actual(repr(st));
+  std::string reason;
+  std::string actual(repr(st));
   bool equal = difftokens(expected, actual, reason);
   if (! equal)
     complainOnNequal(reason, expected, actual, emitDumpFilesOnDiff_);
@@ -634,10 +645,9 @@
 
     // Set function body
     be()->function_set_body(func_, entryBlock_);
-
   }
-    // Finalize export data. This has the side effect of finalizing
-    // debug meta-data, which we need to do before invoking the verifier.
+  // Finalize export data. This has the side effect of finalizing
+  // debug meta-data, which we need to do before invoking the verifier.
   be()->finalizeExportData();
 
   // Strip debug info now if requested
@@ -676,4 +686,4 @@
   return broken || brokenBlock;
 }
 
-} // end namespace goBackEndUnitTests
+} // namespace goBackendUnitTests
diff --git a/unittests/BackendCore/TestUtils.h b/unittests/BackendCore/TestUtils.h
index dccf70e..a75202e 100644
--- a/unittests/BackendCore/TestUtils.h
+++ b/unittests/BackendCore/TestUtils.h
@@ -32,6 +32,9 @@
 
 namespace goBackendUnitTests {
 
+// Convert llvm::CallingConv::ID to its coresponding string name.
+std::string ccName(llvm::CallingConv::ID);
+
 // Return string representation of LLVM value (handling null ptr)
 std::string repr(llvm::Value *val);
 
@@ -152,7 +155,7 @@
  public:
   // Create test harness. If name specified, then create a
   // default function "fcnName(i1, i2 int32) int64".
-  FcnTestHarness(const char *fcnName = nullptr);
+  FcnTestHarness(llvm::CallingConv::ID cconv, const char *fcnName = nullptr);
   ~FcnTestHarness();
 
   // Create function to work on
@@ -206,8 +209,8 @@
 
   // Create and append a switch statement
   Bstatement *mkSwitch(Bexpression *swval,
-                       const std::vector<std::vector<Bexpression*> >& cases,
-                       const std::vector<Bstatement*>& statements,
+                       const std::vector<std::vector<Bexpression*>> &cases,
+                       const std::vector<Bstatement*> &statements,
                        AppendDisp disp = YesAppend);
 
   // Add a previously created statement to the current block