Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nios2: Assembly macros and definitions

This patch add assembly macros and definitions used in
the .S files across arch/nios2/ and together with asm-offsets.c.

Signed-off-by: Ley Foon Tan <lftan@altera.com>

+417
+309
arch/nios2/include/asm/asm-macros.h
··· 1 + /* 2 + * Macro used to simplify coding multi-line assembler. 3 + * Some of the bit test macro can simplify down to one line 4 + * depending on the mask value. 5 + * 6 + * Copyright (C) 2004 Microtronix Datacom Ltd. 7 + * 8 + * All rights reserved. 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License as published by 12 + * the Free Software Foundation; either version 2 of the License, or 13 + * (at your option) any later version. 14 + * 15 + * This program is distributed in the hope that it will be useful, but 16 + * WITHOUT ANY WARRANTY; without even the implied warranty of 17 + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 18 + * NON INFRINGEMENT. See the GNU General Public License for more 19 + * details. 20 + * 21 + */ 22 + #ifndef _ASM_NIOS2_ASMMACROS_H 23 + #define _ASM_NIOS2_ASMMACROS_H 24 + /* 25 + * ANDs reg2 with mask and places the result in reg1. 26 + * 27 + * You cannnot use the same register for reg1 & reg2. 28 + */ 29 + 30 + .macro ANDI32 reg1, reg2, mask 31 + .if \mask & 0xffff 32 + .if \mask & 0xffff0000 33 + movhi \reg1, %hi(\mask) 34 + movui \reg1, %lo(\mask) 35 + and \reg1, \reg1, \reg2 36 + .else 37 + andi \reg1, \reg2, %lo(\mask) 38 + .endif 39 + .else 40 + andhi \reg1, \reg2, %hi(\mask) 41 + .endif 42 + .endm 43 + 44 + /* 45 + * ORs reg2 with mask and places the result in reg1. 46 + * 47 + * It is safe to use the same register for reg1 & reg2. 48 + */ 49 + 50 + .macro ORI32 reg1, reg2, mask 51 + .if \mask & 0xffff 52 + .if \mask & 0xffff0000 53 + orhi \reg1, \reg2, %hi(\mask) 54 + ori \reg1, \reg2, %lo(\mask) 55 + .else 56 + ori \reg1, \reg2, %lo(\mask) 57 + .endif 58 + .else 59 + orhi \reg1, \reg2, %hi(\mask) 60 + .endif 61 + .endm 62 + 63 + /* 64 + * XORs reg2 with mask and places the result in reg1. 65 + * 66 + * It is safe to use the same register for reg1 & reg2. 67 + */ 68 + 69 + .macro XORI32 reg1, reg2, mask 70 + .if \mask & 0xffff 71 + .if \mask & 0xffff0000 72 + xorhi \reg1, \reg2, %hi(\mask) 73 + xori \reg1, \reg1, %lo(\mask) 74 + .else 75 + xori \reg1, \reg2, %lo(\mask) 76 + .endif 77 + .else 78 + xorhi \reg1, \reg2, %hi(\mask) 79 + .endif 80 + .endm 81 + 82 + /* 83 + * This is a support macro for BTBZ & BTBNZ. It checks 84 + * the bit to make sure it is valid 32 value. 85 + * 86 + * It is safe to use the same register for reg1 & reg2. 87 + */ 88 + 89 + .macro BT reg1, reg2, bit 90 + .if \bit > 31 91 + .err 92 + .else 93 + .if \bit < 16 94 + andi \reg1, \reg2, (1 << \bit) 95 + .else 96 + andhi \reg1, \reg2, (1 << (\bit - 16)) 97 + .endif 98 + .endif 99 + .endm 100 + 101 + /* 102 + * Tests the bit in reg2 and branches to label if the 103 + * bit is zero. The result of the bit test is stored in reg1. 104 + * 105 + * It is safe to use the same register for reg1 & reg2. 106 + */ 107 + 108 + .macro BTBZ reg1, reg2, bit, label 109 + BT \reg1, \reg2, \bit 110 + beq \reg1, r0, \label 111 + .endm 112 + 113 + /* 114 + * Tests the bit in reg2 and branches to label if the 115 + * bit is non-zero. The result of the bit test is stored in reg1. 116 + * 117 + * It is safe to use the same register for reg1 & reg2. 118 + */ 119 + 120 + .macro BTBNZ reg1, reg2, bit, label 121 + BT \reg1, \reg2, \bit 122 + bne \reg1, r0, \label 123 + .endm 124 + 125 + /* 126 + * Tests the bit in reg2 and then compliments the bit in reg2. 127 + * The result of the bit test is stored in reg1. 128 + * 129 + * It is NOT safe to use the same register for reg1 & reg2. 130 + */ 131 + 132 + .macro BTC reg1, reg2, bit 133 + .if \bit > 31 134 + .err 135 + .else 136 + .if \bit < 16 137 + andi \reg1, \reg2, (1 << \bit) 138 + xori \reg2, \reg2, (1 << \bit) 139 + .else 140 + andhi \reg1, \reg2, (1 << (\bit - 16)) 141 + xorhi \reg2, \reg2, (1 << (\bit - 16)) 142 + .endif 143 + .endif 144 + .endm 145 + 146 + /* 147 + * Tests the bit in reg2 and then sets the bit in reg2. 148 + * The result of the bit test is stored in reg1. 149 + * 150 + * It is NOT safe to use the same register for reg1 & reg2. 151 + */ 152 + 153 + .macro BTS reg1, reg2, bit 154 + .if \bit > 31 155 + .err 156 + .else 157 + .if \bit < 16 158 + andi \reg1, \reg2, (1 << \bit) 159 + ori \reg2, \reg2, (1 << \bit) 160 + .else 161 + andhi \reg1, \reg2, (1 << (\bit - 16)) 162 + orhi \reg2, \reg2, (1 << (\bit - 16)) 163 + .endif 164 + .endif 165 + .endm 166 + 167 + /* 168 + * Tests the bit in reg2 and then resets the bit in reg2. 169 + * The result of the bit test is stored in reg1. 170 + * 171 + * It is NOT safe to use the same register for reg1 & reg2. 172 + */ 173 + 174 + .macro BTR reg1, reg2, bit 175 + .if \bit > 31 176 + .err 177 + .else 178 + .if \bit < 16 179 + andi \reg1, \reg2, (1 << \bit) 180 + andi \reg2, \reg2, %lo(~(1 << \bit)) 181 + .else 182 + andhi \reg1, \reg2, (1 << (\bit - 16)) 183 + andhi \reg2, \reg2, %lo(~(1 << (\bit - 16))) 184 + .endif 185 + .endif 186 + .endm 187 + 188 + /* 189 + * Tests the bit in reg2 and then compliments the bit in reg2. 190 + * The result of the bit test is stored in reg1. If the 191 + * original bit was zero it branches to label. 192 + * 193 + * It is NOT safe to use the same register for reg1 & reg2. 194 + */ 195 + 196 + .macro BTCBZ reg1, reg2, bit, label 197 + BTC \reg1, \reg2, \bit 198 + beq \reg1, r0, \label 199 + .endm 200 + 201 + /* 202 + * Tests the bit in reg2 and then compliments the bit in reg2. 203 + * The result of the bit test is stored in reg1. If the 204 + * original bit was non-zero it branches to label. 205 + * 206 + * It is NOT safe to use the same register for reg1 & reg2. 207 + */ 208 + 209 + .macro BTCBNZ reg1, reg2, bit, label 210 + BTC \reg1, \reg2, \bit 211 + bne \reg1, r0, \label 212 + .endm 213 + 214 + /* 215 + * Tests the bit in reg2 and then sets the bit in reg2. 216 + * The result of the bit test is stored in reg1. If the 217 + * original bit was zero it branches to label. 218 + * 219 + * It is NOT safe to use the same register for reg1 & reg2. 220 + */ 221 + 222 + .macro BTSBZ reg1, reg2, bit, label 223 + BTS \reg1, \reg2, \bit 224 + beq \reg1, r0, \label 225 + .endm 226 + 227 + /* 228 + * Tests the bit in reg2 and then sets the bit in reg2. 229 + * The result of the bit test is stored in reg1. If the 230 + * original bit was non-zero it branches to label. 231 + * 232 + * It is NOT safe to use the same register for reg1 & reg2. 233 + */ 234 + 235 + .macro BTSBNZ reg1, reg2, bit, label 236 + BTS \reg1, \reg2, \bit 237 + bne \reg1, r0, \label 238 + .endm 239 + 240 + /* 241 + * Tests the bit in reg2 and then resets the bit in reg2. 242 + * The result of the bit test is stored in reg1. If the 243 + * original bit was zero it branches to label. 244 + * 245 + * It is NOT safe to use the same register for reg1 & reg2. 246 + */ 247 + 248 + .macro BTRBZ reg1, reg2, bit, label 249 + BTR \reg1, \reg2, \bit 250 + bne \reg1, r0, \label 251 + .endm 252 + 253 + /* 254 + * Tests the bit in reg2 and then resets the bit in reg2. 255 + * The result of the bit test is stored in reg1. If the 256 + * original bit was non-zero it branches to label. 257 + * 258 + * It is NOT safe to use the same register for reg1 & reg2. 259 + */ 260 + 261 + .macro BTRBNZ reg1, reg2, bit, label 262 + BTR \reg1, \reg2, \bit 263 + bne \reg1, r0, \label 264 + .endm 265 + 266 + /* 267 + * Tests the bits in mask against reg2 stores the result in reg1. 268 + * If the all the bits in the mask are zero it branches to label. 269 + * 270 + * It is safe to use the same register for reg1 & reg2. 271 + */ 272 + 273 + .macro TSTBZ reg1, reg2, mask, label 274 + ANDI32 \reg1, \reg2, \mask 275 + beq \reg1, r0, \label 276 + .endm 277 + 278 + /* 279 + * Tests the bits in mask against reg2 stores the result in reg1. 280 + * If the any of the bits in the mask are 1 it branches to label. 281 + * 282 + * It is safe to use the same register for reg1 & reg2. 283 + */ 284 + 285 + .macro TSTBNZ reg1, reg2, mask, label 286 + ANDI32 \reg1, \reg2, \mask 287 + bne \reg1, r0, \label 288 + .endm 289 + 290 + /* 291 + * Pushes reg onto the stack. 292 + */ 293 + 294 + .macro PUSH reg 295 + addi sp, sp, -4 296 + stw \reg, 0(sp) 297 + .endm 298 + 299 + /* 300 + * Pops the top of the stack into reg. 301 + */ 302 + 303 + .macro POP reg 304 + ldw \reg, 0(sp) 305 + addi sp, sp, 4 306 + .endm 307 + 308 + 309 + #endif /* _ASM_NIOS2_ASMMACROS_H */
+20
arch/nios2/include/asm/asm-offsets.h
··· 1 + /* 2 + * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch> 3 + * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 + * 18 + */ 19 + 20 + #include <generated/asm-offsets.h>
+88
arch/nios2/kernel/asm-offsets.c
··· 1 + /* 2 + * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + * 17 + */ 18 + 19 + #include <linux/stddef.h> 20 + #include <linux/sched.h> 21 + #include <linux/kernel_stat.h> 22 + #include <linux/ptrace.h> 23 + #include <linux/hardirq.h> 24 + #include <linux/thread_info.h> 25 + #include <linux/kbuild.h> 26 + 27 + int main(void) 28 + { 29 + /* struct task_struct */ 30 + OFFSET(TASK_THREAD, task_struct, thread); 31 + BLANK(); 32 + 33 + /* struct thread_struct */ 34 + OFFSET(THREAD_KSP, thread_struct, ksp); 35 + OFFSET(THREAD_KPSR, thread_struct, kpsr); 36 + BLANK(); 37 + 38 + /* struct pt_regs */ 39 + OFFSET(PT_ORIG_R2, pt_regs, orig_r2); 40 + OFFSET(PT_ORIG_R7, pt_regs, orig_r7); 41 + 42 + OFFSET(PT_R1, pt_regs, r1); 43 + OFFSET(PT_R2, pt_regs, r2); 44 + OFFSET(PT_R3, pt_regs, r3); 45 + OFFSET(PT_R4, pt_regs, r4); 46 + OFFSET(PT_R5, pt_regs, r5); 47 + OFFSET(PT_R6, pt_regs, r6); 48 + OFFSET(PT_R7, pt_regs, r7); 49 + OFFSET(PT_R8, pt_regs, r8); 50 + OFFSET(PT_R9, pt_regs, r9); 51 + OFFSET(PT_R10, pt_regs, r10); 52 + OFFSET(PT_R11, pt_regs, r11); 53 + OFFSET(PT_R12, pt_regs, r12); 54 + OFFSET(PT_R13, pt_regs, r13); 55 + OFFSET(PT_R14, pt_regs, r14); 56 + OFFSET(PT_R15, pt_regs, r15); 57 + OFFSET(PT_EA, pt_regs, ea); 58 + OFFSET(PT_RA, pt_regs, ra); 59 + OFFSET(PT_FP, pt_regs, fp); 60 + OFFSET(PT_SP, pt_regs, sp); 61 + OFFSET(PT_GP, pt_regs, gp); 62 + OFFSET(PT_ESTATUS, pt_regs, estatus); 63 + DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs)); 64 + BLANK(); 65 + 66 + /* struct switch_stack */ 67 + OFFSET(SW_R16, switch_stack, r16); 68 + OFFSET(SW_R17, switch_stack, r17); 69 + OFFSET(SW_R18, switch_stack, r18); 70 + OFFSET(SW_R19, switch_stack, r19); 71 + OFFSET(SW_R20, switch_stack, r20); 72 + OFFSET(SW_R21, switch_stack, r21); 73 + OFFSET(SW_R22, switch_stack, r22); 74 + OFFSET(SW_R23, switch_stack, r23); 75 + OFFSET(SW_FP, switch_stack, fp); 76 + OFFSET(SW_GP, switch_stack, gp); 77 + OFFSET(SW_RA, switch_stack, ra); 78 + DEFINE(SWITCH_STACK_SIZE, sizeof(struct switch_stack)); 79 + BLANK(); 80 + 81 + /* struct thread_info */ 82 + OFFSET(TI_TASK, thread_info, task); 83 + OFFSET(TI_FLAGS, thread_info, flags); 84 + OFFSET(TI_PREEMPT_COUNT, thread_info, preempt_count); 85 + BLANK(); 86 + 87 + return 0; 88 + }