2 * Copyright (C) 2003-2013 Altera Corporation
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.
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.
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/>.
20 #include <linux/linkage.h>
21 #include <asm/entry.h>
27 * Explicitly allow the use of r1 (the assembler temporary register)
28 * within this code. This register is normally reserved for the use of
32 ENTRY(instruction_trap)
33 ldw r1, PT_R1(sp) // Restore registers
51 ldw et, PT_ESTATUS(sp)
54 ldw et, PT_SP(sp) /* backup sp in et */
56 addi sp, sp, PT_REGS_SIZE
58 /* INSTRUCTION EMULATION
59 * ---------------------
61 * Nios II processors generate exceptions for unimplemented instructions.
62 * The routines below emulate these instructions. Depending on the
63 * processor core, the only instructions that might need to be emulated
64 * are div, divu, mul, muli, mulxss, mulxsu, and mulxuu.
66 * The emulations match the instructions, except for the following
69 * 1) The emulation routines do not emulate the use of the exception
70 * temporary register (et) as a source operand because the exception
71 * handler already has modified it.
73 * 2) The routines do not emulate the use of the stack pointer (sp) or
74 * the exception return address register (ea) as a destination because
75 * modifying these registers crashes the exception handler or the
76 * interrupted routine.
81 * The emulation routines expect the contents of integer registers r0-r31
82 * to be on the stack at addresses sp, 4(sp), 8(sp), ... 124(sp). The
83 * routines retrieve source operands from the stack and modify the
84 * destination register's value on the stack prior to the end of the
85 * exception handler. Then all registers except the destination register
86 * are restored to their previous values.
88 * The instruction that causes the exception is found at address -4(ea).
89 * The instruction's OP and OPX fields identify the operation to be
92 * One instruction, muli, is an I-type instruction that is identified by
93 * an OP field of 0x24.
95 * muli AAAAA,BBBBB,IIIIIIIIIIIIIIII,-0x24-
96 * 27 22 6 0 <-- LSB of field
98 * The remaining emulated instructions are R-type and have an OP field
99 * of 0x3a. Their OPX fields identify them.
101 * R-type AAAAA,BBBBB,CCCCC,XXXXXX,NNNNN,-0x3a-
102 * 27 22 17 11 6 0 <-- LSB of field
105 * Opcode Encoding. muli is identified by its OP value. Then OPX & 0x02
106 * is used to differentiate between the division opcodes and the
107 * remaining multiplication opcodes.
109 * Instruction OP OPX OPX & 0x02
110 * ----------- ---- ---- ----------
115 * mulxuu 0x3a 0x07 != 0
116 * mulxsu 0x3a 0x17 != 0
117 * mulxss 0x3a 0x1f != 0
122 * Save everything on the stack to make it easy for the emulation
123 * routines to retrieve the source register operands.
127 stw zero, 0(sp) /* Save zero on stack to avoid special case for r0. */
151 /* Don't bother to save et. It's already been changed. */
156 stw et, 108(sp) /* et contains previous sp value. */
163 * Split the instruction into its fields. We need 4*A, 4*B, and 4*C as
164 * offsets to the stack pointer for access to the stored register values.
166 ldw r2,-4(ea) /* r2 = AAAAA,BBBBB,IIIIIIIIIIIIIIII,PPPPPP */
167 roli r3, r2, 7 /* r3 = BBB,IIIIIIIIIIIIIIII,PPPPPP,AAAAA,BB */
168 roli r4, r3, 3 /* r4 = IIIIIIIIIIIIIIII,PPPPPP,AAAAA,BBBBB */
169 roli r5, r4, 2 /* r5 = IIIIIIIIIIIIII,PPPPPP,AAAAA,BBBBB,II */
170 srai r4, r4, 16 /* r4 = (sign-extended) IMM16 */
171 roli r6, r5, 5 /* r6 = XXXX,NNNNN,PPPPPP,AAAAA,BBBBB,CCCCC,XX */
172 andi r2, r2, 0x3f /* r2 = 00000000000000000000000000,PPPPPP */
173 andi r3, r3, 0x7c /* r3 = 0000000000000000000000000,AAAAA,00 */
174 andi r5, r5, 0x7c /* r5 = 0000000000000000000000000,BBBBB,00 */
175 andi r6, r6, 0x7c /* r6 = 0000000000000000000000000,CCCCC,00 */
180 * r4 = IMM16 (sign extended)
188 * It is necessary to check for muli because it uses an I-type
189 * instruction format, while the other instructions are have an R-type
192 * Prepare for either multiplication or division loop.
193 * They both loop 32 times.
197 add r3, r3, sp /* r3 = address of A-operand. */
198 ldw r3, 0(r3) /* r3 = A-operand. */
199 movi r7, 0x24 /* muli opcode (I-type instruction format) */
200 beq r2, r7, mul_immed /* muli doesn't use the B register as a source */
202 add r5, r5, sp /* r5 = address of B-operand. */
203 ldw r5, 0(r5) /* r5 = B-operand. */
204 /* r4 = SSSSSSSSSSSSSSSS,-----IMM16------ */
205 /* IMM16 not needed, align OPX portion */
206 /* r4 = SSSSSSSSSSSSSSSS,CCCCC,-OPX--,00000 */
207 srli r4, r4, 5 /* r4 = 00000,SSSSSSSSSSSSSSSS,CCCCC,-OPX-- */
208 andi r4, r4, 0x3f /* r4 = 00000000000000000000000000,-OPX-- */
214 * r4 = OPX (no longer can be muli)
220 * Multiply or Divide?
222 andi r7, r4, 0x02 /* For R-type multiply instructions,
224 bne r7, zero, multiply
229 * Divide an unsigned dividend by an unsigned divisor using
230 * a shift-and-subtract algorithm. The example below shows
231 * 43 div 7 = 6 for 8-bit integers. This classic algorithm uses a
232 * single register to store both the dividend and the quotient,
233 * allowing both values to be shifted with a single instruction.
235 * remainder dividend:quotient
236 * --------- -----------------
237 * initialize 00000000 00101011:
238 * shift 00000000 0101011:_
239 * remainder >= divisor? no 00000000 0101011:0
240 * shift 00000000 101011:0_
241 * remainder >= divisor? no 00000000 101011:00
242 * shift 00000001 01011:00_
243 * remainder >= divisor? no 00000001 01011:000
244 * shift 00000010 1011:000_
245 * remainder >= divisor? no 00000010 1011:0000
246 * shift 00000101 011:0000_
247 * remainder >= divisor? no 00000101 011:00000
248 * shift 00001010 11:00000_
249 * remainder >= divisor? yes 00001010 11:000001
250 * remainder -= divisor - 00000111
253 * shift 00000111 1:000001_
254 * remainder >= divisor? yes 00000111 1:0000011
255 * remainder -= divisor - 00000111
258 * shift 00000001 :0000011_
259 * remainder >= divisor? no 00000001 :00000110
261 * The quotient is 00000110.
266 * Prepare for division by assuming the result
267 * is unsigned, and storing its "sign" as 0.
272 /* Which division opcode? */
273 xori r7, r4, 0x25 /* OPX of div */
274 bne r7, zero, unsigned_division
278 * OPX is div. Determine and store the sign of the quotient.
279 * Then take the absolute value of both operands.
281 xor r17, r3, r5 /* MSB contains sign of quotient */
282 bge r3,zero,dividend_is_nonnegative
283 sub r3, zero, r3 /* -r3 */
284 dividend_is_nonnegative:
285 bge r5, zero, divisor_is_nonnegative
286 sub r5, zero, r5 /* -r5 */
287 divisor_is_nonnegative:
291 /* Initialize the unsigned-division loop. */
292 movi r13, 0 /* remainder = 0 */
295 * r3 = dividend : quotient
296 * r4 = 0x25 for div, 0x24 for divu
299 * r14 = loop counter (already initialized to 32)
300 * r17 = MSB contains sign of quotient
305 * for (count = 32; count > 0; --count)
313 * (remainder:dividend:quotient) <<= 1;
316 cmplt r7, r3, zero /* r7 = MSB of r3 */
322 * if (remainder >= divisor)
324 * set LSB of quotient
325 * remainder -= divisor;
328 bltu r13, r5, div_skip
337 bne r14, zero, divide_loop
342 * r4 = 0x25 for div, 0x24 for divu
344 * r17 = MSB contains sign of quotient
349 * Conditionally negate signed quotient. If quotient is unsigned,
350 * the sign already is initialized to 0.
352 bge r17, zero, quotient_is_nonnegative
353 sub r3, zero, r3 /* -r3 */
354 quotient_is_nonnegative:
358 * Final quotient is in r3.
361 stw r3, 0(r6) /* write quotient to stack */
369 * A "product" is the number that one gets by summing a "multiplicand"
370 * several times. The "multiplier" specifies the number of copies of the
371 * multiplicand that are summed.
373 * Actual multiplication algorithms don't use repeated addition, however.
374 * Shift-and-add algorithms get the same answer as repeated addition, and
375 * they are faster. To compute the lower half of a product (pppp below)
376 * one shifts the product left before adding in each of the partial
377 * products (a * mmmm) through (d * mmmm).
379 * To compute the upper half of a product (PPPP below), one adds in the
380 * partial products (d * mmmm) through (a * mmmm), each time following
381 * the add by a right shift of the product.
393 * The example above shows 4 partial products. Computing actual Nios II
394 * products requires 32 partials.
396 * It is possible to compute the result of mulxsu from the result of
397 * mulxuu because the only difference between the results of these two
398 * opcodes is the value of the partial product associated with the sign
401 * mulxsu = mulxuu - (rA < 0) ? rB : 0;
403 * It is possible to compute the result of mulxss from the result of
404 * mulxsu because the only difference between the results of these two
405 * opcodes is the value of the partial product associated with the sign
408 * mulxss = mulxsu - (rB < 0) ? rA : 0;
413 /* Opcode is muli. Change it into mul for remainder of algorithm. */
414 mov r6, r5 /* Field B is dest register, not field C. */
415 mov r5, r4 /* Field IMM16 is src2, not field B. */
416 movi r4, 0x27 /* OPX of mul is 0x27 */
419 /* Initialize the multiplication loop. */
420 movi r9, 0 /* mul_product = 0 */
421 movi r10, 0 /* mulxuu_product = 0 */
422 mov r11, r5 /* save original multiplier for mulxsu and mulxss */
423 mov r12, r5 /* mulxuu_multiplier (will be shifted) */
424 movi r16, 1 /* used to create "rori B,A,1" from "ror B,A,r16" */
428 * r5 = mul_multiplier
429 * r6 = 4 * dest_register (used later as offset to sp)
432 * r10 = mulxuu_product
433 * r11 = original multiplier
434 * r12 = mulxuu_multiplier
435 * r14 = loop counter (already initialized)
441 * for (count = 32; count > 0; --count)
448 * lsb = multiplier & 1;
456 * mulxuu_product += multiplicand;
459 beq r7, zero, mulx_skip
461 cmpltu r7, r10, r3 /* Save the carry from the MSB of mulxuu_product. */
462 ror r7, r7, r16 /* r7 = 0x80000000 on carry, or else 0x00000000 */
466 * if (MSB of mul_multiplier == 1)
468 * mul_product += multiplicand;
471 bge r5, zero, mul_skip
476 * mulxuu_product >>= 1; logical shift
477 * mul_multiplier <<= 1; done with MSB
478 * mulx_multiplier >>= 1; done with LSB
481 or r10, r10, r7 /* OR in the saved carry bit. */
490 bne r14, zero, multiply_loop
494 * Multiply emulation loop done.
500 * r6 = 4 * dest_register (used later as offset to sp)
503 * r10 = mulxuu_product
504 * r11 = original multiplier
508 /* Calculate address for result from 4 * dest_register */
513 * Select/compute the result based on OPX.
517 /* OPX == mul? Then store. */
519 beq r7, zero, store_product
521 /* It's one of the mulx.. opcodes. Move over the result. */
524 /* OPX == mulxuu? Then store. */
526 beq r7, zero, store_product
530 * mulxsu = mulxuu - (rA < 0) ? rB : 0;
532 bge r3, zero, mulxsu_skip
536 /* OPX == mulxsu? Then store. */
538 beq r7, zero, store_product
542 * mulxss = mulxsu - (rB < 0) ? rA : 0;
544 bge r11,zero,mulxss_skip
547 /* At this point, assume that OPX is mulxss, so store*/
555 /* No need to restore r0. */
582 /* Does not need to restore et */
588 ldw sp, 108(sp) /* last restore sp */