From 378ed6f0e3c525e3b12827e7b7fb0a078ee48a32 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 8 Nov 2018 20:14:38 +0000 Subject: MIPS: Avoid using .set mips0 to restore ISA We currently have 2 commonly used methods for switching ISA within assembly code, then restoring the original ISA. 1) Using a pair of .set push & .set pop directives. For example: .set push .set mips32r2 .set pop 2) Using .set mips0 to restore the ISA originally specified on the command line. For example: .set mips32r2 .set mips0 Unfortunately method 2 does not work with nanoMIPS toolchains, where the assembler rejects the .set mips0 directive like so: Error: cannot change ISA from nanoMIPS to mips0 In preparation for supporting nanoMIPS builds, switch all instances of method 2 in generic non-platform-specific code to use push & pop as in method 1 instead. The .set push & .set pop is arguably cleaner anyway, and if nothing else it's good to consistently use one method. Signed-off-by: Paul Burton Patchwork: https://patchwork.linux-mips.org/patch/21037/ Cc: linux-mips@linux-mips.org --- arch/mips/include/asm/mipsregs.h | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'arch/mips/include/asm/mipsregs.h') diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 341a02c92985..402b80af91aa 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1345,9 +1345,10 @@ do { \ : "=r" (__res)); \ else \ __asm__ vol( \ + ".set\tpush\n\t" \ ".set\tmips32\n\t" \ "mfc0\t%0, " #source ", " #sel "\n\t" \ - ".set\tmips0\n\t" \ + ".set\tpop\n\t" \ : "=r" (__res)); \ __res; \ }) @@ -1358,15 +1359,17 @@ do { \ __res = __read_64bit_c0_split(source, sel, vol); \ else if (sel == 0) \ __asm__ vol( \ + ".set\tpush\n\t" \ ".set\tmips3\n\t" \ "dmfc0\t%0, " #source "\n\t" \ - ".set\tmips0" \ + ".set\tpop" \ : "=r" (__res)); \ else \ __asm__ vol( \ + ".set\tpush\n\t" \ ".set\tmips64\n\t" \ "dmfc0\t%0, " #source ", " #sel "\n\t" \ - ".set\tmips0" \ + ".set\tpop" \ : "=r" (__res)); \ __res; \ }) @@ -1391,9 +1394,10 @@ do { \ : : "Jr" ((unsigned int)(value))); \ else \ __asm__ __volatile__( \ + ".set\tpush\n\t" \ ".set\tmips32\n\t" \ "mtc0\t%z0, " #register ", " #sel "\n\t" \ - ".set\tmips0" \ + ".set\tpop" \ : : "Jr" ((unsigned int)(value))); \ } while (0) @@ -1403,15 +1407,17 @@ do { \ __write_64bit_c0_split(register, sel, value); \ else if (sel == 0) \ __asm__ __volatile__( \ + ".set\tpush\n\t" \ ".set\tmips3\n\t" \ "dmtc0\t%z0, " #register "\n\t" \ - ".set\tmips0" \ + ".set\tpop" \ : : "Jr" (value)); \ else \ __asm__ __volatile__( \ + ".set\tpush\n\t" \ ".set\tmips64\n\t" \ "dmtc0\t%z0, " #register ", " #sel "\n\t" \ - ".set\tmips0" \ + ".set\tpop" \ : : "Jr" (value)); \ } while (0) @@ -1463,19 +1469,21 @@ do { \ local_irq_save(__flags); \ if (sel == 0) \ __asm__ vol( \ + ".set\tpush\n\t" \ ".set\tmips64\n\t" \ "dmfc0\t%L0, " #source "\n\t" \ "dsra\t%M0, %L0, 32\n\t" \ "sll\t%L0, %L0, 0\n\t" \ - ".set\tmips0" \ + ".set\tpop" \ : "=r" (__val)); \ else \ __asm__ vol( \ + ".set\tpush\n\t" \ ".set\tmips64\n\t" \ "dmfc0\t%L0, " #source ", " #sel "\n\t" \ "dsra\t%M0, %L0, 32\n\t" \ "sll\t%L0, %L0, 0\n\t" \ - ".set\tmips0" \ + ".set\tpop" \ : "=r" (__val)); \ local_irq_restore(__flags); \ \ @@ -1498,23 +1506,25 @@ do { \ : "+r" (__tmp)); \ else if (sel == 0) \ __asm__ __volatile__( \ + ".set\tpush\n\t" \ ".set\tmips64\n\t" \ "dsll\t%L0, %L0, 32\n\t" \ "dsrl\t%L0, %L0, 32\n\t" \ "dsll\t%M0, %M0, 32\n\t" \ "or\t%L0, %L0, %M0\n\t" \ "dmtc0\t%L0, " #source "\n\t" \ - ".set\tmips0" \ + ".set\tpop" \ : "+r" (__tmp)); \ else \ __asm__ __volatile__( \ + ".set\tpush\n\t" \ ".set\tmips64\n\t" \ "dsll\t%L0, %L0, 32\n\t" \ "dsrl\t%L0, %L0, 32\n\t" \ "dsll\t%M0, %M0, 32\n\t" \ "or\t%L0, %L0, %M0\n\t" \ "dmtc0\t%L0, " #source ", " #sel "\n\t" \ - ".set\tmips0" \ + ".set\tpop" \ : "+r" (__tmp)); \ local_irq_restore(__flags); \ } while (0) -- cgit