arch/parisc/math-emu/decode_exc.c

Source file repositories/reference/linux-study-clean/arch/parisc/math-emu/decode_exc.c

File Facts

System
Linux kernel
Corpus path
arch/parisc/math-emu/decode_exc.c
Extension
.c
Size
10943 bytes
Lines
358
Domain
Architecture Layer
Bucket
arch/parisc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!Is_tbit_set()) {
	update_trap_counts(Fpu_register, aflags, bflags, trap_counts);
	return SIGNALCODE(SIGILL, ILL_COPROC);
    }

    /* 
     * Is a coprocessor op. 
     *
     * Now we need to determine what type of exception occurred.
     */
    for (exception_index=1; exception_index<=MAX_EXCP_REG; exception_index++) {
	current_ir = Excp_instr(exception_index);
	  /*
	   * On PA89: there are 5 different unimplemented exception
	   * codes: 0x1, 0x9, 0xb, 0x3, and 0x23.  PA-RISC 2.0 adds
	   * another, 0x2b.  Only these have the low order bit set.
	   */
	excptype = Excp_type(exception_index);
	if (excptype & UNIMPLEMENTEDEXCEPTION) {
		/*
		 * Clear T-bit and exception register so that
		 * we can tell if a trap really occurs while 
		 * emulating the instruction.
		 */
		Clear_tbit();
		Clear_excp_register(exception_index);
		/*
		 * Now emulate this instruction.  If a trap occurs,
		 * fpudispatch will return a non-zero number 
		 */
		excp = fpudispatch(current_ir,excptype,0,Fpu_register);
		/* accumulate the status flags, don't lose them as in hpux */
		if (excp) {
			/*
			 * We now need to make sure that the T-bit and the
			 * exception register contain the correct values
			 * before continuing.
			 */
			/*
			 * Set t-bit since it might still be needed for a
			 * subsequent real trap (I don't understand fully -PB)
			 */
			Set_tbit();
			/* some of the following code uses
			 * Excp_type(exception_index) so fix that up */
			Set_exceptiontype_and_instr_field(excp,current_ir,
			 Fpu_register[exception_index]);
			if (excp == UNIMPLEMENTEDEXCEPTION) {
				/*
			 	 * it is really unimplemented, so restore the
			 	 * TIMEX extended unimplemented exception code
			 	 */
				excp = excptype;
				update_trap_counts(Fpu_register, aflags, bflags, 
					   trap_counts);
				return SIGNALCODE(SIGILL, ILL_COPROC);
			}
			/* some of the following code uses excptype, so
			 * fix that up too */
			excptype = excp;
		}
		/* handle exceptions other than the real UNIMPLIMENTED the
		 * same way as if the hardware had caused them */
		if (excp == NOEXCEPTION)
			/* For now use 'break', should technically be 'continue' */
			break;
	}

	  /*
	   * In PA89, the underflow exception has been extended to encode
	   * additional information.  The exception looks like pp01x0,
	   * where x is 1 if inexact and pp represent the inexact bit (I)
	   * and the round away bit (RA)
	   */
	if (excptype & UNDERFLOWEXCEPTION) {
		/* check for underflow trap enabled */
		if (Is_underflowtrap_enabled()) {
			update_trap_counts(Fpu_register, aflags, bflags, 
					   trap_counts);
			return SIGNALCODE(SIGFPE, FPE_FLTUND);
		} else {
		    /*
		     * Isn't a real trap; we need to 
		     * return the default value.
		     */
		    target = current_ir & fivebits;
#ifndef lint
		    if (Ibit(Fpu_register[exception_index])) inexact = TRUE;
		    else inexact = FALSE;
#endif

Annotation

Implementation Notes