Index: src/base/cpu.cc |
diff --git a/src/base/cpu.cc b/src/base/cpu.cc |
index fbfbcf683b74e3014257cfe749e96eabdf2203cf..cd40d4f62150b2b48b01d6bc81f2e1165b677a82 100644 |
--- a/src/base/cpu.cc |
+++ b/src/base/cpu.cc |
@@ -119,13 +119,18 @@ static uint32_t ReadELFHWCaps() { |
int __detect_fp64_mode(void) { |
double result = 0; |
// Bit representation of (double)1 is 0x3FF0000000000000. |
- asm( |
- "lui $t0, 0x3FF0\n\t" |
- "ldc1 $f0, %0\n\t" |
- "mtc1 $t0, $f1\n\t" |
- "sdc1 $f0, %0\n\t" |
- : "+m" (result) |
- : : "t0", "$f0", "$f1", "memory"); |
+ __asm__ volatile( |
+ ".set push\n\t" |
+ ".set noreorder\n\t" |
+ ".set oddspreg\n\t" |
+ "lui $t0, 0x3FF0\n\t" |
+ "ldc1 $f0, %0\n\t" |
+ "mtc1 $t0, $f1\n\t" |
+ "sdc1 $f0, %0\n\t" |
+ ".set pop\n\t" |
+ : "+m"(result) |
+ : |
+ : "t0", "$f0", "$f1", "memory"); |
return !(result == 1); |
} |
@@ -133,9 +138,22 @@ int __detect_fp64_mode(void) { |
int __detect_mips_arch_revision(void) { |
// TODO(dusmil): Do the specific syscall as soon as it is implemented in mips |
- // kernel. Currently fail-back to the least common denominator which is |
- // mips32 revision 1. |
- return 1; |
+ // kernel. |
+ uint32_t result = 0; |
+ __asm__ volatile( |
+ "move $v0, $zero\n\t" |
+ // Encoding for "addi $v0, $v0, 1" on non-r6, |
+ // which is encoding for "bovc $v0, %v0, 1" on r6. |
+ // Use machine code directly to avoid compilation errors with different |
+ // toolchains and maintain compatibility. |
+ ".word 0x20420001\n\t" |
+ "sw $v0, %0\n\t" |
+ : "=m"(result) |
+ : |
+ : "v0", "memory"); |
+ // Result is 0 on r6 architectures, 1 on other architecture revisions. |
+ // Fall-back to the least common denominator which is mips32 revision 1. |
+ return result ? 1 : 6; |
} |
#endif |