* mips/crt0.S: Configure processor based on .MIPS.abiflags.
Remove FPU availability check, just use the pre-processor flags to indicicate what the user wanted. * mips/abiflags.S: New file. * mips/regs.S (SR_MSA): Define macro. * mips/mti32.ld: Place .MIPS.abiflags and wrap in marker symbols. * mips/mti64.ld: Likewise. * mips/mti64_64.ld: Likewise. * mips/mti64_n32.ld: Likewise.
This commit is contained in:
		
							
								
								
									
										82
									
								
								libgloss/mips/abiflags.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								libgloss/mips/abiflags.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
/*
 | 
			
		||||
 * abiflags.S - MIPS ABI flags.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Values for the xxx_size bytes of an ABI flags structure.  */
 | 
			
		||||
#define AFL_REG_NONE         0x00       /* No registers.  */
 | 
			
		||||
#define AFL_REG_32           0x01       /* 32-bit registers.  */
 | 
			
		||||
#define AFL_REG_64           0x02       /* 64-bit registers.  */
 | 
			
		||||
#define AFL_REG_128          0x03       /* 128-bit registers.  */
 | 
			
		||||
 | 
			
		||||
/* Masks for the ases word of an ABI flags structure.  */
 | 
			
		||||
#define AFL_ASE_DSP          0x00000001  /* DSP ASE.  */
 | 
			
		||||
#define AFL_ASE_DSPR2        0x00000002  /* DSP R2 ASE.  */
 | 
			
		||||
#define AFL_ASE_EVA          0x00000004  /* Enhanced VA Scheme.  */
 | 
			
		||||
#define AFL_ASE_MCU          0x00000008  /* MCU (MicroController) ASE.  */
 | 
			
		||||
#define AFL_ASE_MDMX         0x00000010  /* MDMX ASE.  */
 | 
			
		||||
#define AFL_ASE_MIPS3D       0x00000020  /* MIPS-3D ASE.  */
 | 
			
		||||
#define AFL_ASE_MT           0x00000040  /* MT ASE.  */
 | 
			
		||||
#define AFL_ASE_SMARTMIPS    0x00000080  /* SmartMIPS ASE.  */
 | 
			
		||||
#define AFL_ASE_VIRT         0x00000100  /* VZ ASE.  */
 | 
			
		||||
#define AFL_ASE_MSA          0x00000200  /* MSA ASE.  */
 | 
			
		||||
#define AFL_ASE_MIPS16       0x00000400  /* MIPS16 ASE.  */
 | 
			
		||||
#define AFL_ASE_MICROMIPS    0x00000800  /* MICROMIPS ASE.  */
 | 
			
		||||
#define AFL_ASE_XPA          0x00001000  /* XPA ASE.  */
 | 
			
		||||
 | 
			
		||||
/* Values for the isa_ext word of an ABI flags structure.  */
 | 
			
		||||
#define AFL_EXT_XLR           1  /* RMI Xlr instruction.  */
 | 
			
		||||
#define AFL_EXT_OCTEON2       2  /* Cavium Networks Octeon2.  */
 | 
			
		||||
#define AFL_EXT_OCTEONP       3  /* Cavium Networks OcteonP.  */
 | 
			
		||||
#define AFL_EXT_LOONGSON_3A   4  /* Loongson 3A.  */
 | 
			
		||||
#define AFL_EXT_OCTEON        5  /* Cavium Networks Octeon.  */
 | 
			
		||||
#define AFL_EXT_5900          6  /* MIPS R5900 instruction.  */
 | 
			
		||||
#define AFL_EXT_4650          7  /* MIPS R4650 instruction.  */
 | 
			
		||||
#define AFL_EXT_4010          8  /* LSI R4010 instruction.  */
 | 
			
		||||
#define AFL_EXT_4100          9  /* NEC VR4100 instruction.  */
 | 
			
		||||
#define AFL_EXT_3900         10  /* Toshiba R3900 instruction.  */
 | 
			
		||||
#define AFL_EXT_10000        11  /* MIPS R10000 instruction.  */
 | 
			
		||||
#define AFL_EXT_SB1          12  /* Broadcom SB-1 instruction.  */
 | 
			
		||||
#define AFL_EXT_4111         13  /* NEC VR4111/VR4181 instruction.  */
 | 
			
		||||
#define AFL_EXT_4120         14  /* NEC VR4120 instruction.  */
 | 
			
		||||
#define AFL_EXT_5400         15  /* NEC VR5400 instruction.  */
 | 
			
		||||
#define AFL_EXT_5500         16  /* NEC VR5500 instruction.  */
 | 
			
		||||
#define AFL_EXT_LOONGSON_2E  17  /* ST Microelectronics Loongson 2E.  */
 | 
			
		||||
#define AFL_EXT_LOONGSON_2F  18  /* ST Microelectronics Loongson 2F.  */
 | 
			
		||||
 | 
			
		||||
/* Values defined for Tag_GNU_MIPS_ABI_FP.  */
 | 
			
		||||
#define Val_GNU_MIPS_ABI_FP_ANY    0  /* Not tagged or not using any ABIs affected by the differences.  */
 | 
			
		||||
#define Val_GNU_MIPS_ABI_FP_DOUBLE 1  /* Using hard-float -mdouble-float.  */
 | 
			
		||||
#define Val_GNU_MIPS_ABI_FP_SINGLE 2  /* Using hard-float -msingle-float.  */
 | 
			
		||||
#define Val_GNU_MIPS_ABI_FP_SOFT   3  /* Using soft-float.  */
 | 
			
		||||
#define Val_GNU_MIPS_ABI_FP_OLD_64 4  /* Using -mips32r2 -mfp64.  */
 | 
			
		||||
#define Val_GNU_MIPS_ABI_FP_XX     5  /* Using -mfpxx */
 | 
			
		||||
#define Val_GNU_MIPS_ABI_FP_64     6  /* Using -mips32r2 -mfp64.  */
 | 
			
		||||
#define Val_GNU_MIPS_ABI_MSA_ANY   0  /* Not tagged or not using any ABIs affected by the differences.  */
 | 
			
		||||
#define Val_GNU_MIPS_ABI_MSA_128   1  /* Using 128-bit MSA.  */
 | 
			
		||||
 | 
			
		||||
/* MIPS ABI flags structure */
 | 
			
		||||
  .struct 0
 | 
			
		||||
ABIFlags_version:
 | 
			
		||||
  .struct ABIFlags_version + 2
 | 
			
		||||
ABIFlags_isa_level:
 | 
			
		||||
  .struct ABIFlags_isa_level + 1
 | 
			
		||||
ABIFlags_isa_rev:
 | 
			
		||||
  .struct ABIFlags_isa_rev + 1
 | 
			
		||||
ABIFlags_gpr_size:
 | 
			
		||||
  .struct ABIFlags_gpr_size + 1
 | 
			
		||||
ABIFlags_cpr1_size:
 | 
			
		||||
  .struct ABIFlags_cpr1_size + 1
 | 
			
		||||
ABIFlags_cpr2_size:
 | 
			
		||||
  .struct ABIFlags_cpr2_size + 1
 | 
			
		||||
ABIFlags_fp_abi:
 | 
			
		||||
  .struct ABIFlags_fp_abi + 1
 | 
			
		||||
ABIFlags_isa_ext:
 | 
			
		||||
  .struct ABIFlags_isa_ext + 4
 | 
			
		||||
ABIFlags_ases:
 | 
			
		||||
  .struct ABIFlags_ases + 4
 | 
			
		||||
ABIFlags_flags1:
 | 
			
		||||
  .struct ABIFlags_flags1 + 4
 | 
			
		||||
ABIFlags_flags2:
 | 
			
		||||
  .struct ABIFlags_flags2 + 4
 | 
			
		||||
 | 
			
		||||
/*> EOF abiflags.S <*/
 | 
			
		||||
@@ -14,12 +14,16 @@
 | 
			
		||||
 * they apply.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* This file does not use any floating-point ABI.  */
 | 
			
		||||
	.gnu_attribute 4,0
 | 
			
		||||
 | 
			
		||||
#ifdef __mips16
 | 
			
		||||
/* This file contains 32 bit assembly code.  */
 | 
			
		||||
	.set nomips16
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "regs.S"
 | 
			
		||||
#include "abiflags.S"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Set up some room for a stack. We just grab a chunk of memory.
 | 
			
		||||
@@ -82,45 +86,86 @@ _start:
 | 
			
		||||
#    endif
 | 
			
		||||
#  endif
 | 
			
		||||
#endif
 | 
			
		||||
	li	v0, STATUS_MASK
 | 
			
		||||
	mtc0	v0, C0_SR
 | 
			
		||||
	mtc0	zero, C0_CAUSE
 | 
			
		||||
 | 
			
		||||
	/* Clear Cause register.  */
 | 
			
		||||
	mtc0	zero,C0_CAUSE
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	/* Avoid hazard from FPU enable and other SR changes.  */
 | 
			
		||||
	LA (t0, hardware_hazard_hook)
 | 
			
		||||
	beq	t0,zero,1f
 | 
			
		||||
	jalr	t0
 | 
			
		||||
	/* Read MIPS_abiflags structure and set status/config registers
 | 
			
		||||
	   accordingly.  */
 | 
			
		||||
	.weak	__MIPS_abiflags_start
 | 
			
		||||
	.weak	__MIPS_abiflags_end
 | 
			
		||||
	LA	(t0,__MIPS_abiflags_start)
 | 
			
		||||
	LA	(t1,__MIPS_abiflags_end)
 | 
			
		||||
	addiu	t1,t1,-24
 | 
			
		||||
	move	v0,zero			/* Mask for C0_SR.  */
 | 
			
		||||
 | 
			
		||||
	/* Branch to 1f is the .MIPS.abiflags section is not 24 bytes.  This
 | 
			
		||||
	   indicates it is either missing or corrupt.  */
 | 
			
		||||
	bne	t0,t1,1f
 | 
			
		||||
 | 
			
		||||
	/* Check isa_level.  */
 | 
			
		||||
	lbu	t1,ABIFlags_isa_level(t0)
 | 
			
		||||
	sltu	v1,t1,3			/* Is MIPS < 3?  */
 | 
			
		||||
	xori	t1,t1,64		/* Is MIPS64?  */
 | 
			
		||||
	beq	v1,zero,4f
 | 
			
		||||
	li	v1,SR_PE
 | 
			
		||||
	or	v0,v0,v1		/* Enable soft reset.  */
 | 
			
		||||
4:
 | 
			
		||||
	li	v1,(SR_KX|SR_SX|SR_UX)
 | 
			
		||||
	bne	t1,zero,5f
 | 
			
		||||
	or	v0,v0,v1		/* Enable extended addressing.  */
 | 
			
		||||
5:
 | 
			
		||||
	/* Check fp_abi.  */
 | 
			
		||||
	lbu	t1,ABIFlags_fp_abi(t0)
 | 
			
		||||
	xori	t1,t1,Val_GNU_MIPS_ABI_FP_SOFT
 | 
			
		||||
	li	v1,SR_CU1
 | 
			
		||||
	beq	t1,zero,2f		/* Skip MSA and cpr1_size checks.  */
 | 
			
		||||
	or	v0,v0,v1		/* Enable co-processor 1.  */
 | 
			
		||||
 | 
			
		||||
	/* Check cpr1_size.  */
 | 
			
		||||
	lbu	t1,ABIFlags_cpr1_size(t0)
 | 
			
		||||
	xori	t1,t1,AFL_REG_64
 | 
			
		||||
	li	v1,SR_FR
 | 
			
		||||
	bne	t1,zero,3f
 | 
			
		||||
	or	v0,v0,v1		/* Enable 64-bit FPU registers.  */
 | 
			
		||||
3:
 | 
			
		||||
	/* Check ases.  */
 | 
			
		||||
	lw	t1,ABIFlags_ases(t0)
 | 
			
		||||
	andi	t1,t1,AFL_ASE_MSA
 | 
			
		||||
	li	v1,SR_FR
 | 
			
		||||
	beq	t1,zero,2f
 | 
			
		||||
	or	v0,v0,v1		/* Enable 64-bit FPU registers.  */
 | 
			
		||||
	li	v1,SR_MSA
 | 
			
		||||
	.set	push
 | 
			
		||||
	.set	mips32
 | 
			
		||||
	mtc0	v1,C0_CONFIG,5		/* Enable MSA.  */
 | 
			
		||||
	.set	pop
 | 
			
		||||
	b	2f
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
 | 
			
		||||
/* Check for FPU presence.  Don't check if we know that soft_float is
 | 
			
		||||
   being used.  (This also avoids illegal instruction exceptions.)  */
 | 
			
		||||
 | 
			
		||||
#ifndef __mips_soft_float
 | 
			
		||||
	li	t2,0xAAAA5555
 | 
			
		||||
	mtc1	t2,fp0		/* write to FPR 0 */
 | 
			
		||||
	mtc1	zero,fp1	/* write to FPR 1 */
 | 
			
		||||
	mfc1	t0,fp0
 | 
			
		||||
	mfc1	t1,fp1
 | 
			
		||||
	nop
 | 
			
		||||
	bne	t0,t2,1f	/* check for match */
 | 
			
		||||
	bne	t1,zero,1f	/* double check */
 | 
			
		||||
	j	2f		/* FPU is present. */
 | 
			
		||||
	/* MIPS_abiflags structure is not available.  Set status/config
 | 
			
		||||
	   registers based on flags defined by compiler.  */
 | 
			
		||||
#ifdef __mips_soft_float
 | 
			
		||||
	li	v0,(STATUS_MASK-(STATUS_MASK & SR_CU1))
 | 
			
		||||
#else
 | 
			
		||||
	li	v0,STATUS_MASK
 | 
			
		||||
#endif
 | 
			
		||||
1:
 | 
			
		||||
	/* FPU is not present.  Set status register to say that. */
 | 
			
		||||
	li	v0, (STATUS_MASK-(STATUS_MASK & SR_CU1))
 | 
			
		||||
	mtc0	v0, C0_SR
 | 
			
		||||
 | 
			
		||||
2:
 | 
			
		||||
	/* Set C0_SR,  */
 | 
			
		||||
	mtc0	v0,C0_SR
 | 
			
		||||
	nop
 | 
			
		||||
	/* Avoid hazard from FPU disable.  */
 | 
			
		||||
	LA (t0, hardware_hazard_hook)
 | 
			
		||||
 | 
			
		||||
	/* Avoid hazard from C0_SR changes.  */
 | 
			
		||||
	LA	(t0, hardware_hazard_hook)
 | 
			
		||||
	beq	t0,zero,2f
 | 
			
		||||
	jalr	t0
 | 
			
		||||
2:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Fix high bits, if any, of the PC so that exception handling
 | 
			
		||||
   doesn't get confused.  */
 | 
			
		||||
/* Fix high bits, if any, of the PC so that exception handling doesn't get
 | 
			
		||||
   confused.  */
 | 
			
		||||
	LA (v0, 3f)
 | 
			
		||||
	jr	v0
 | 
			
		||||
3:
 | 
			
		||||
 
 | 
			
		||||
@@ -93,6 +93,11 @@ SECTIONS
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  . = .;
 | 
			
		||||
  .MIPS.abiflags : {
 | 
			
		||||
    __MIPS_abiflags_start = .;
 | 
			
		||||
    *(.MIPS.abiflags)
 | 
			
		||||
    __MIPS_abiflags_end = .;
 | 
			
		||||
  }
 | 
			
		||||
  .rodata : {
 | 
			
		||||
    *(.rdata)
 | 
			
		||||
    *(.rodata)
 | 
			
		||||
@@ -137,6 +142,7 @@ SECTIONS
 | 
			
		||||
    *(COMMON)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  . = ALIGN(4);
 | 
			
		||||
  PROVIDE (end = .);
 | 
			
		||||
  _end = .;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -95,6 +95,11 @@ SECTIONS
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  . = .;
 | 
			
		||||
  .MIPS.abiflags : {
 | 
			
		||||
    __MIPS_abiflags_start = .;
 | 
			
		||||
    *(.MIPS.abiflags)
 | 
			
		||||
    __MIPS_abiflags_end = .;
 | 
			
		||||
  }
 | 
			
		||||
  .rodata : {
 | 
			
		||||
    *(.rdata)
 | 
			
		||||
    *(.rodata)
 | 
			
		||||
@@ -139,6 +144,7 @@ SECTIONS
 | 
			
		||||
    *(COMMON)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  . = ALIGN(4);
 | 
			
		||||
  PROVIDE (end = .);
 | 
			
		||||
  _end = .;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -98,6 +98,11 @@ SECTIONS
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  . = .;
 | 
			
		||||
  .MIPS.abiflags : {
 | 
			
		||||
    __MIPS_abiflags_start = .;
 | 
			
		||||
    *(.MIPS.abiflags)
 | 
			
		||||
    __MIPS_abiflags_end = .;
 | 
			
		||||
  }
 | 
			
		||||
  .rodata : {
 | 
			
		||||
    *(.rdata)
 | 
			
		||||
    *(.rodata)
 | 
			
		||||
@@ -142,6 +147,7 @@ SECTIONS
 | 
			
		||||
    *(COMMON)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  . = ALIGN(4);
 | 
			
		||||
  PROVIDE (end = .);
 | 
			
		||||
  _end = .;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -98,6 +98,11 @@ SECTIONS
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  . = .;
 | 
			
		||||
  .MIPS.abiflags : {
 | 
			
		||||
    __MIPS_abiflags_start = .;
 | 
			
		||||
    *(.MIPS.abiflags)
 | 
			
		||||
    __MIPS_abiflags_end = .;
 | 
			
		||||
  }
 | 
			
		||||
  .rodata : {
 | 
			
		||||
    *(.rdata)
 | 
			
		||||
    *(.rodata)
 | 
			
		||||
@@ -142,6 +147,7 @@ SECTIONS
 | 
			
		||||
    *(COMMON)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  . = ALIGN(4);
 | 
			
		||||
  PROVIDE (end = .);
 | 
			
		||||
  _end = .;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -98,6 +98,8 @@
 | 
			
		||||
#define SR_SX		0x00000040	/* Supervisor extended addressing enabled */
 | 
			
		||||
#define SR_UX		0x00000020	/* User extended addressing enabled */
 | 
			
		||||
 | 
			
		||||
#define SR_MSA		0x08000000	/* MSA ASE */
 | 
			
		||||
 | 
			
		||||
/* Standard (R4000) cache operations. Taken from "MIPS R4000
 | 
			
		||||
   Microprocessor User's Manual" 2nd edition: */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user