Merge commit '0e0fd6c2' into manualmerge
diff --git a/main/Android.mk b/main/Android.mk
index bcd8858..8ac1d80 100644
--- a/main/Android.mk
+++ b/main/Android.mk
@@ -46,13 +46,16 @@
 ANDROID_HARDWARE := ANDROID_HARDWARE_nexus_10
 else ifeq ($(TARGET_BOOTLOADER_BOARD_NAME),grouper)
 ANDROID_HARDWARE := ANDROID_HARDWARE_nexus_7
+else ifeq ($(TARGET_BOOTLOADER_BOARD_NAME),MAKO)
+ANDROID_HARDWARE := ANDROID_HARDWARE_nexus_4
 endif
-common_cflags += -D$(ANDROID_HARDWARE)
 
 else
 tool_ldflags := -static -Wl,-Ttext=0x38000000 -nodefaultlibs -nostartfiles -u _start -e_start
 endif
 
+common_cflags += -D$(ANDROID_HARDWARE)
+
 preload_ldflags := -nodefaultlibs -Wl,-z,interpose,-z,initfirst
 # Remove this when the all toolchains are GCC 4.4
 ifeq ($(TARGET_ARCH),arm)
@@ -255,7 +258,9 @@
 
 LOCAL_LDFLAGS := $(vex_ldflags)
 
+# TODO: split asflags out from cflags.
 LOCAL_CFLAGS := $(common_cflags)
+LOCAL_ASFLAGS := $(common_cflags)
 
 include $(BUILD_STATIC_LIBRARY)
 
diff --git a/main/VEX/priv/guest_arm_toIR.c b/main/VEX/priv/guest_arm_toIR.c
index 220c50f..372c927 100644
--- a/main/VEX/priv/guest_arm_toIR.c
+++ b/main/VEX/priv/guest_arm_toIR.c
@@ -14602,6 +14602,30 @@
       }
    }
 
+   /* ------------------- smmla ------------------ */
+   if (INSN(27,20) == BITS8(0,1,1,1,0,1,0,1)
+       && INSN(15,12) != BITS4(1,1,1,1)
+       && (INSN(7,4) & BITS4(1,1,0,1)) == BITS4(0,0,0,1)) {
+      UInt bitR = INSN(5,5);
+      UInt rD = INSN(19,16);
+      UInt rA = INSN(15,12);
+      UInt rM = INSN(11,8);
+      UInt rN = INSN(3,0);
+      if (rD != 15 && rM != 15 && rN != 15) {
+         IRExpr* res
+         = unop(Iop_64HIto32,
+                binop(Iop_Add64,
+                      binop(Iop_Add64,
+                            binop(Iop_32HLto64, getIRegA(rA), mkU32(0)),
+                            binop(Iop_MullS32, getIRegA(rN), getIRegA(rM))),
+                      mkU64(bitR ? 0x80000000ULL : 0ULL)));
+         putIRegA(rD, res, condT, Ijk_Boring);
+         DIP("smmla%s%s r%u, r%u, r%u, r%u\n",
+             nCC(INSN_COND), bitR ? "r" : "", rD, rN, rM, rA);
+         goto decode_success;
+      }
+   }
+
    /* ------------------- NOP ------------------ */
    if (0x0320F000 == (insn & 0x0FFFFFFF)) {
       DIP("nop%s\n", nCC(INSN_COND));
@@ -18802,6 +18826,30 @@
       }
    }
 
+   /* ------------------- (T1) SMMLA{R} ------------------ */
+   if (INSN0(15,7) == BITS9(1,1,1,1,1,0,1,1,0)
+       && INSN0(6,4) == BITS3(1,0,1)
+       && INSN1(7,5) == BITS3(0,0,0)) {
+      UInt bitR = INSN1(4,4);
+      UInt rA = INSN1(15,12);
+      UInt rD = INSN1(11,8);
+      UInt rM = INSN1(3,0);
+      UInt rN = INSN0(3,0);
+      if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM) && (rA != 13)) {
+         IRExpr* res
+         = unop(Iop_64HIto32,
+                binop(Iop_Add64,
+                      binop(Iop_Add64,
+                            binop(Iop_32HLto64, getIRegT(rA), mkU32(0)),
+                            binop(Iop_MullS32, getIRegT(rN), getIRegT(rM))),
+                      mkU64(bitR ? 0x80000000ULL : 0ULL)));
+         putIRegT(rD, res, condT);
+         DIP("smmla%s r%u, r%u, r%u, r%u\n",
+             bitR ? "r" : "", rD, rN, rM, rA);
+         goto decode_success;
+      }
+   }
+
    /* ----------------------------------------------------------- */
    /* -- VFP (CP 10, CP 11) instructions (in Thumb mode)       -- */
    /* ----------------------------------------------------------- */
diff --git a/main/coregrind/m_syswrap/syswrap-linux.c b/main/coregrind/m_syswrap/syswrap-linux.c
index 0b4a98b..8e2ec0f 100644
--- a/main/coregrind/m_syswrap/syswrap-linux.c
+++ b/main/coregrind/m_syswrap/syswrap-linux.c
@@ -4308,11 +4308,8 @@
    case 0x7231:
    case 0x4004e901: /* used by NFC */
       return;
-#  elif defined(ANDROID_HARDWARE_nexus_7)
-   /* undocumented ioctl ids noted on the device */
-   case 0x4e04:
-   case 0x7231:
-      return;
+#  elif defined(ANDROID_HARDWARE_nexus_4)
+
 #  endif
 
    default:
@@ -5563,6 +5560,13 @@
    case VKI_EVIOCSSUSPENDBLOCK:
       break;
 
+   case VKI_MEDIA_IOC_DEVICE_INFO:
+      if (ARG3) {
+         PRE_MEM_WRITE("ioctl(MEDIA_IOC_DEVICE_INFO)", ARG3,
+                       sizeof(struct vki_media_device_info));
+      }
+      break;
+
    default:
       /* EVIOC* are variable length and return size written on success */
       switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
@@ -5680,6 +5684,8 @@
 
 #  elif defined(ANDROID_HARDWARE_nexus_7)
 
+#  elif defined(ANDROID_HARDWARE_nexus_4)
+
 #  else /* no ANDROID_HARDWARE_anything defined */
 
 #   warning ""
@@ -5690,6 +5696,7 @@
 #   warning "   ANDROID_HARDWARE_nexus_s       Samsung Nexus S"
 #   warning "   ANDROID_HARDWARE_nexus_10      Samsung Nexus 10"
 #   warning "   ANDROID_HARDWARE_nexus_7       ASUS Nexus 7"
+#   warning "   ANDROID_HARDWARE_nexus_4       LG Nexus 4"
 #   warning "   ANDROID_HARDWARE_generic       Generic device (eg, Pandaboard)"
 #   warning "   ANDROID_HARDWARE_emulator      x86 or arm emulator"
 #   warning ""
@@ -6576,6 +6583,12 @@
       POST_MEM_WRITE( ARG3, sizeof(int) );
       break;
 
+   case VKI_MEDIA_IOC_DEVICE_INFO:
+      if (ARG3) {
+         POST_MEM_WRITE(ARG3, sizeof(struct vki_media_device_info));
+      }
+      break;
+
    default:
       /* EVIOC* are variable length and return size written on success */
       switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
diff --git a/main/include/vki/vki-linux.h b/main/include/vki/vki-linux.h
index 8cefd8f..214a626 100644
--- a/main/include/vki/vki-linux.h
+++ b/main/include/vki/vki-linux.h
@@ -3011,6 +3011,23 @@
 #define VKI_UI_SET_SWBIT		_VKI_IOW(VKI_UINPUT_IOCTL_BASE, 109, int)
 #define VKI_UI_SET_PROPBIT		_VKI_IOW(VKI_UINPUT_IOCTL_BASE, 110, int)
 
+//----------------------------------------------------------------------
+// From include/linux/media.h
+//----------------------------------------------------------------------
+
+struct vki_media_device_info {
+    char driver[16];
+    char model[32];
+    char serial[40];
+    char bus_info[32];
+    __vki_u32 media_version;
+    __vki_u32 hw_revision;
+    __vki_u32 driver_version;
+    __vki_u32 reserved[31];
+};
+
+#define VKI_MEDIA_IOC_DEVICE_INFO _VKI_IOWR('|', 0x00, struct vki_media_device_info)
+
 #endif // __VKI_LINUX_H
 
 /*--------------------------------------------------------------------*/