1/*
2** Copyright 2003, Axel D���fler, axeld@pinc-software.de. All rights reserved.
3** Distributed under the terms of the MIT License.
4*/
5
6#include <asm_defs.h>
7
8.text
9
10/* uint16 __swap_int16(uint16 value)
11 *					   r3
12 */
13FUNCTION(__swap_int16):
14		rlwinm	%r4, %r3, 8, 16, 23		// byte 4 -> byte 3 (clear other bits)
15		rlwimi	%r4, %r3, 24, 24, 31		// byte 3 -> byte 4 (copy into)
16		mr		%r3, %r4				// copy to result register
17		blr
18
19
20/* uint32 __swap_int32(uint32 value)
21 *					   r3
22 */
23FUNCTION(__swap_int32):
24		lwbrx	%r4, 0, %r3		// Load and inverse r3 into r4
25		mr		%r3, %r4
26		blr
27
28
29/* uint64 __swap_int64(uint64 value)
30 *					   r3/r4
31 */
32FUNCTION(__swap_int64):
33		lwbrx	%r5, 0, %r3
34		mr		%r3, %r5
35		lwbrx	%r5, 0, %r4
36		mr		%r4, %r5		// copy lower 32 bits
37		blr
38
39
40/* TODO: The following functions can surely be optimized. A simple optimization
41 * would be to define macros with the contents of the __swap_int{32,64}
42 * functions and use those instead of calling the functions.
43 */
44
45/* float __swap_float(float value)
46 *					  f1
47 */
48FUNCTION(__swap_float):
49		// push a stack frame
50		stwu	%r1, -32(%r1)
51		mflr	%r0
52		stw		%r0, 36(%r1)
53
54		// %f1 -> %r3
55		stfs	%f1, 20(%r1)
56		lwz		%r3, 20(%r1)
57
58		// let __swap_int32 convert %r3
59		bl		__swap_int32
60
61		// %r3 -> %f1
62		stw		%r3, 20(%r1)
63		lfs		%f1, 20(%r1)
64
65		// pop the stack frame
66		lwz		%r0, 36(%r1)
67		mtlr	%r0
68		addi	%r1, %r1, 32
69		blr
70
71/* double __swap_double(double value)
72 *						f1
73 */
74FUNCTION(__swap_double):
75		// push a stack frame
76		stwu	%r1, -32(%r1)
77		mflr	%r0
78		stw		%r0, 36(%r1)
79
80		// %f1 -> (%r3:%r4)
81		stfd	%f1, 20(%r1)
82		lwz		%r3, 20(%r1)
83		lwz		%r4, 24(%r1)
84
85		// let __swap_int64 convert %r3:%r4
86		bl		__swap_int64
87
88		// (%r3:%r4) -> %f1
89		stw		%r3, 20(%r1)
90		stw		%r4, 24(%r1)
91		lfd		%f1, 20(%r1)
92
93		// pop the stack frame
94		lwz		%r0, 36(%r1)
95		mtlr	%r0
96		addi	%r1, %r1, 32
97		blr
98