| From 3e9a825d1a217ab02a24d14e80cad993a864079e Mon Sep 17 00:00:00 2001 |
| From: Joel Stanley <joel@jms.id.au> |
| Date: Thu, 22 Jun 2017 13:43:47 +0930 |
| Subject: [PATCH] Convert cmpi to cmpwi to fix build for modern binutils |
| |
| From Linux 80f23935cadb ("powerpc: Convert cmp to cmpd in idle enter sequence"): |
| |
| PowerPC's "cmp" instruction has four operands. Normally people write |
| "cmpw" or "cmpd" for the second cmp operand 0 or 1. But, frequently |
| people forget, and write "cmp" with just three operands. |
| |
| With older binutils this is silently accepted as if this was "cmpw", |
| while often "cmpd" is wanted. With newer binutils GAS will complain |
| about this for 64-bit code. For 32-bit code it still silently assumes |
| "cmpw" is what is meant. |
| |
| In this instance the code comes directly from ISA v2.07, including the |
| cmp, but cmpd is correct. Backport to stable so that new toolchains can |
| build old kernels. |
| |
| This is change is a noop with the existing toolchain. We change from |
| implicitly generating the cmpwi to explicitly stating in for |
| compatibility with newer toolchains. |
| |
| With gcc 4.9.3, binutils 2.25.2: |
| |
| $ cat asm-test.S |
| .text |
| |
| .global test |
| cmpi 0, 8, 1 |
| $ powerpc64-linux-gcc -c asm-test.S |
| $ objdump -d asm-test.o |
| 0000000000000000 <.text>: |
| 2c 08 00 01 cmpwi r8,1 |
| |
| Old compiler, updated instruction: |
| |
| $ cat asm-test.S |
| .text |
| |
| .global test |
| cmpwi 0, 8, 1 |
| $ powerpc64-linux-gcc -c asm-test.S |
| $ objdump -d asm-test.o |
| 0000000000000000 <.text>: |
| 2c 08 00 01 cmpwi r8,1 |
| |
| And then the new toolchain (gcc 6.3.0, binutils 2.28) with the updated |
| asm: |
| |
| $ cat asm-test.S |
| .text |
| |
| .global test |
| cmpwi 0, 8, 1 |
| $ powerpc64-linux-gnu-gcc -c asm-test.S |
| $ objdump -d asm-test.o |
| 0000000000000000 <.text>: |
| 2c 08 00 01 cmpwi r8,1 |
| |
| Change-Id: I878ab3596f54c221879945944f2dfbf053427026 |
| Signed-off-by: Joel Stanley <joel@jms.id.au> |
| Signed-off-by: Joel Stanley <joel.stanley@au1.ibm.com> |
| --- |
| src/kernel/start.S | 34 +++++++++++++++++----------------- |
| src/runtime/rt_start.S | 2 +- |
| 2 files changed, 18 insertions(+), 18 deletions(-) |
| |
| diff --git a/src/kernel/start.S b/src/kernel/start.S |
| index 6474a2ced794..5015b652e407 100644 |
| --- a/src/kernel/start.S |
| +++ b/src/kernel/start.S |
| @@ -199,7 +199,7 @@ UNIMPL_INTERRUPT(hype_decrementer, 0x980) |
| ;// |
| .org _start + 0xC00 |
| intvect_system_call_fast: |
| - cmpi cr0, r3, 0x0800 |
| + cmpwi cr0, r3, 0x0800 |
| bge cr0, system_call_fast_path |
| STD_INTERRUPT(system_call, 0xC08) |
| |
| @@ -292,7 +292,7 @@ _other_thread_spinlock: |
| 1: |
| ld r3, 0(r2) |
| ;// Loop until value is 1... |
| - cmpi cr0, r3, 1 |
| + cmpwi cr0, r3, 1 |
| beq _other_thread_spinlock_complete |
| or 1,1,1 ;// Lower thread priority. |
| b 1b |
| @@ -307,12 +307,12 @@ _other_thread_spinlock_complete: |
| extrwi r1, r1, 3, 19 |
| sldi r1, r1, 3 |
| ldx r2, r1, r2 ;// Dereference to get on-node CPUs array. |
| - cmpi cr0, r2, 0 ;// Check for NULL node array. |
| + cmpwi cr0, r2, 0 ;// Check for NULL node array. |
| beq- 1f |
| mfspr r1, PIR ;// Extract on-node CPU id. |
| clrlslwi r1, r1, 22, 3 |
| ldx r3, r1, r2 ;// Load CPU object. |
| - cmpi cr0, r3, 0 ;// Check for NULL CPU object. |
| + cmpwi cr0, r3, 0 ;// Check for NULL CPU object. |
| beq- 1f |
| ld r1, CPU_KERNEL_STACK(r3) ;// Load initial stack. |
| |
| @@ -388,7 +388,7 @@ kernel_save_task: |
| std r31, TASK_GPR_31(r1) ;// Save GPR31 |
| |
| ld r2, TASK_FP_CONTEXT(r1) ;// Load FP Context pointer. |
| - cmpi cr0, r2, 0 |
| + cmpwi cr0, r2, 0 |
| bne- cr0, 1f ;// Jump to FP-save if != NULL. |
| 2: |
| |
| @@ -470,7 +470,7 @@ kernel_dispatch_task: |
| |
| ;// Check if FP enabled, load context. |
| ld r2, TASK_FP_CONTEXT(r1) |
| - cmpi cr0, r2, 0 |
| + cmpwi cr0, r2, 0 |
| bne- 1f |
| 2: |
| ;// Restore GPRs from context. |
| @@ -587,7 +587,7 @@ intvect_system_reset: |
| lis r2, kernel_other_thread_spinlock@h |
| ori r2, r2, kernel_other_thread_spinlock@l |
| ld r2, 0(r2) |
| - cmpi cr0, r2, 0 |
| + cmpwi cr0, r2, 0 |
| beq- _start |
| |
| ;// Get CPU object from thread ID, check for NULL which implies not |
| @@ -598,12 +598,12 @@ intvect_system_reset: |
| extrwi r1, r1, 3, 19 |
| sldi r1, r1, 3 |
| ldx r2, r1, r2 ;// Dereference to get on-node CPUs array. |
| - cmpi cr0, r2, 0 ;// Check for NULL node array. |
| + cmpwi cr0, r2, 0 ;// Check for NULL node array. |
| beq- _start |
| mfspr r1, PIR ;// Extract on-node CPU id. |
| clrlslwi r1, r1, 22, 3 |
| ldx r2, r1, r2 ;// Load CPU object. |
| - cmpi cr0, r2, 0 ;// Check for NULL CPU object. |
| + cmpwi cr0, r2, 0 ;// Check for NULL CPU object. |
| beq- _start |
| |
| ;// Check for inactive CPU. |
| @@ -617,13 +617,13 @@ intvect_system_reset: |
| mfsrr1 r2 |
| extrdi r2, r2, 3, 42 |
| ;// Check for decrementer (bits = 011). |
| - cmpi cr0, r2, 0x3 |
| + cmpwi cr0, r2, 0x3 |
| beq+ intvect_system_reset_decrementer |
| ;// Check for external interrupt (bits = 010). |
| - cmpi cr0, r2, 0x4 |
| + cmpwi cr0, r2, 0x4 |
| beq+ intvect_system_reset_external |
| ;// Check for HMI (bits = 101). |
| - cmpi cr0, r2, 0x5 |
| + cmpwi cr0, r2, 0x5 |
| beq+ 1f ;// Unable to handle HMI, jump to 'unknown reason'. |
| |
| 1: ;// Unknown reason, call as unhandled_exception. |
| @@ -721,14 +721,14 @@ system_call_fast_path: |
| b 1f ;// Jump to exit point. |
| ;// Check if this is HMER write (0x801). |
| 2: |
| - cmpi cr0, r3, 0x801 |
| + cmpwi cr0, r3, 0x801 |
| bne cr0, 3f |
| mtspr HMER, r4 |
| li r3, 0 |
| b 1f ;// Jump to exit point. |
| ;// Check if this is SCRATCH read (0x802). |
| 3: |
| - cmpi cr0, r3, 0x802 |
| + cmpwi cr0, r3, 0x802 |
| bne cr0, 4f |
| ;// Check for being on master processor. |
| mfsprg3 r6 ;// Get task structure. |
| @@ -755,7 +755,7 @@ system_call_fast_path: |
| b intvect_system_call |
| ;// Check if this is SCRATCH write (0x803). |
| 4: |
| - cmpi cr0, r3, 0x803 |
| + cmpwi cr0, r3, 0x803 |
| bne cr0, 5f |
| ;// Check for master processor. |
| mfsprg3 r6 ;// Get task structure. |
| @@ -770,7 +770,7 @@ system_call_fast_path: |
| b 1f ;// Jump to exit point. |
| ;// Check if this is PVR read (0x804). |
| 5: |
| - cmpi cr0, r3, 0x804 |
| + cmpwi cr0, r3, 0x804 |
| bne cr0, 6f |
| mfspr r3, PVR |
| b 1f ;// Jump to exit point. |
| @@ -800,7 +800,7 @@ system_call_fast_path: |
| .global userspace_task_entry |
| userspace_task_entry: |
| ;// Skip stack frame if GPR1 == NULL. |
| - cmpi cr0, r1, 0 |
| + cmpwi cr0, r1, 0 |
| beq- 1f |
| ;// Create frame. |
| ;// NULL back-chain + 48 bytes + quad-word alignment. See ABI. |
| diff --git a/src/runtime/rt_start.S b/src/runtime/rt_start.S |
| index d69184aef29f..821e9f956b8e 100644 |
| --- a/src/runtime/rt_start.S |
| +++ b/src/runtime/rt_start.S |
| @@ -47,7 +47,7 @@ _init: |
| |
| ld r8, 0(r10) # Get count of relocations. |
| |
| - cmpi cr0, r8, 0 # Perform relocations (if any). |
| + cmpwi cr0, r8, 0 # Perform relocations (if any). |
| beq 2f |
| mtctr r8 |
| 1: |
| -- |
| 2.13.1 |
| |