aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2010-08-13 16:37:00 -0400
committerChris Metcalf <cmetcalf@tilera.com>2010-08-13 16:37:00 -0400
commitba00376b0b13f234d839541a7b36a5bf5c2a4036 (patch)
tree9f74c7d7933d969484859365f055b5a77cfc4fd1 /arch/tile
parentc745a8a11fa1df6078bfc61fc29492ed43f71c2b (diff)
arch/tile: extend syscall ABI to set r1 on return as well.
Until now, the tile architecture ABI for syscall return has just been that r0 holds the return value, and an error is only signalled like it is for kernel code, with a negative small number. However, this means that in multiple places in userspace we end up writing the same three-cycle idiom that tests for a small negative number for error. It seems cleaner to instead move that code into the kernel, and set r1 to hold zero on success or errno on failure; previously, r1 was just zeroed on return from the kernel (to avoid leaking kernel state). This way a single conditional branch after the syscall is sufficient to test for the failure case. The number of cycles taken is the same, but the error-checking code is in just one place, so total code size is smaller, and random userspace syscall code is easier to understand. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile')
-rw-r--r--arch/tile/kernel/intvec_32.S14
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index 3404c75f8e64..84f296ca9e63 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -952,7 +952,7 @@ STD_ENTRY(interrupt_return)
952 * able to safely read all the remaining words on those cache 952 * able to safely read all the remaining words on those cache
953 * lines without waiting for the memory subsystem. 953 * lines without waiting for the memory subsystem.
954 */ 954 */
955 pop_reg_zero r0, r1, sp, PTREGS_OFFSET_REG(30) - PTREGS_OFFSET_REG(0) 955 pop_reg_zero r0, r28, sp, PTREGS_OFFSET_REG(30) - PTREGS_OFFSET_REG(0)
956 pop_reg_zero r30, r2, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(30) 956 pop_reg_zero r30, r2, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(30)
957 pop_reg_zero r21, r3, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC 957 pop_reg_zero r21, r3, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
958 pop_reg_zero lr, r4, sp, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_EX1 958 pop_reg_zero lr, r4, sp, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_EX1
@@ -1017,7 +1017,17 @@ STD_ENTRY(interrupt_return)
1017 { move r22, zero; move r23, zero } 1017 { move r22, zero; move r23, zero }
1018 { move r24, zero; move r25, zero } 1018 { move r24, zero; move r25, zero }
1019 { move r26, zero; move r27, zero } 1019 { move r26, zero; move r27, zero }
1020 { move r28, zero; move r29, zero } 1020
1021 /* Set r1 to errno if we are returning an error, otherwise zero. */
1022 {
1023 moveli r29, 1024
1024 sub r1, zero, r0
1025 }
1026 slt_u r29, r1, r29
1027 {
1028 mnz r1, r29, r1
1029 move r29, zero
1030 }
1021 iret 1031 iret
1022 1032
1023 /* 1033 /*