aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2016-06-08 10:24:00 +0200
committerMike Pall <mike>2016-06-08 10:24:00 +0200
commit287a5347cfe452d44748327fb7c27f6ce57f5dc2 (patch)
tree72ee534bbad2ff069408977f0cb2787527dcdbc2
parentf5983437a6b08c140bdeb2fc15fa30d7f3b0daad (diff)
MIPS: Support MIPS16 interlinking.v2.1
-rw-r--r--doc/install.html2
-rw-r--r--src/jit/dis_mips.lua2
-rw-r--r--src/lib_jit.c4
-rw-r--r--src/lj_emit_mips.h3
-rw-r--r--src/lj_target_mips.h1
5 files changed, 9 insertions, 3 deletions
diff --git a/doc/install.html b/doc/install.html
index 38c9a6b..bbc71c9 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -386,7 +386,7 @@ important to compile with the proper CPU or architecture settings:
<li>The best way to get consistent results is to specify the correct settings when building the toolchain yourself.</li>
<li>For a pre-built, generic toolchain add <tt>-mcpu=...</tt> or <tt>-march=...</tt> and other necessary flags to <tt>TARGET_CFLAGS</tt>.</li>
<li>For ARM it's important to have the correct <tt>-mfloat-abi=...</tt> setting, too. Otherwise LuaJIT may not run at the full performance of your target CPU.</li>
-<li>For MIPS it's important to select a supported ABI (o32 on MIPS32, n64 on MIPS64) and consistently compile your project either with hard-float or soft-float compiler settings. Do not use <tt>-mips16</tt>.</li>
+<li>For MIPS it's important to select a supported ABI (o32 on MIPS32, n64 on MIPS64) and consistently compile your project either with hard-float or soft-float compiler settings.</li>
</ul>
<p>
Here are some examples for targets with a different CPU than the host:
diff --git a/src/jit/dis_mips.lua b/src/jit/dis_mips.lua
index 19327d6..6776f0c 100644
--- a/src/jit/dis_mips.lua
+++ b/src/jit/dis_mips.lua
@@ -214,7 +214,7 @@ local map_pri = {
map_cop0, map_cop1, false, map_cop1x,
"beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB",
false, false, false, false,
- map_special2, false, false, map_special3,
+ map_special2, "jalxJ", false, map_special3,
"lbTSO", "lhTSO", "lwlTSO", "lwTSO",
"lbuTSO", "lhuTSO", "lwrTSO", false,
"sbTSO", "shTSO", "swlTSO", "swTSO",
diff --git a/src/lib_jit.c b/src/lib_jit.c
index 1655f0c..592538b 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -721,8 +721,12 @@ static uint32_t jit_cpudetect(lua_State *L)
#if defined(__GNUC__)
if (!(flags & JIT_F_MIPSXXR2)) {
int x;
+#ifdef __mips16
+ x = 0; /* Runtime detection is difficult. Ensure optimal -march flags. */
+#else
/* On MIPS32R1 rotr is treated as srl. rotr r2,r2,1 -> srl r2,r2,1. */
__asm__("li $2, 1\n\t.long 0x00221042\n\tmove %0, $2" : "=r"(x) : : "$2");
+#endif
if (x) flags |= JIT_F_MIPSXXR2; /* Either 0x80000000 (R2) or 0 (R1). */
}
#endif
diff --git a/src/lj_emit_mips.h b/src/lj_emit_mips.h
index 9df0477..d35f830 100644
--- a/src/lj_emit_mips.h
+++ b/src/lj_emit_mips.h
@@ -157,7 +157,8 @@ static void emit_call(ASMState *as, void *target, int needcfa)
MCode *p = as->mcp;
*--p = MIPSI_NOP;
if ((((uintptr_t)target ^ (uintptr_t)p) >> 28) == 0) {
- *--p = MIPSI_JAL | (((uintptr_t)target >>2) & 0x03ffffffu);
+ *--p = (((uintptr_t)target & 1) ? MIPSI_JALX : MIPSI_JAL) |
+ (((uintptr_t)target >>2) & 0x03ffffffu);
} else { /* Target out of range: need indirect call. */
*--p = MIPSI_JALR | MIPSF_S(RID_CFUNCADDR);
needcfa = 1;
diff --git a/src/lj_target_mips.h b/src/lj_target_mips.h
index ac72528..6a7d4b5 100644
--- a/src/lj_target_mips.h
+++ b/src/lj_target_mips.h
@@ -239,6 +239,7 @@ typedef enum MIPSIns {
MIPSI_B = 0x10000000,
MIPSI_J = 0x08000000,
MIPSI_JAL = 0x0c000000,
+ MIPSI_JALX = 0x74000000,
MIPSI_JR = 0x00000008,
MIPSI_JALR = 0x0000f809,