diff --git a/libgloss/ChangeLog b/libgloss/ChangeLog index f4d5fd486..81c540051 100644 --- a/libgloss/ChangeLog +++ b/libgloss/ChangeLog @@ -1,3 +1,16 @@ +2014-11-28 Jaydeep Patil + Matthew Fortune + + * 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. + 2014-11-26 Matthew Fortune * mips/crt0.S: Remove .set noreorder throughout. diff --git a/libgloss/mips/abiflags.S b/libgloss/mips/abiflags.S new file mode 100644 index 000000000..953caafb4 --- /dev/null +++ b/libgloss/mips/abiflags.S @@ -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 <*/ diff --git a/libgloss/mips/crt0.S b/libgloss/mips/crt0.S index f66ef1bc3..254998242 100644 --- a/libgloss/mips/crt0.S +++ b/libgloss/mips/crt0.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: diff --git a/libgloss/mips/mti32.ld b/libgloss/mips/mti32.ld index 715639ef5..2739c620f 100644 --- a/libgloss/mips/mti32.ld +++ b/libgloss/mips/mti32.ld @@ -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 = .; diff --git a/libgloss/mips/mti64.ld b/libgloss/mips/mti64.ld index 1bd11f6f8..15975ad89 100644 --- a/libgloss/mips/mti64.ld +++ b/libgloss/mips/mti64.ld @@ -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 = .; diff --git a/libgloss/mips/mti64_64.ld b/libgloss/mips/mti64_64.ld index a058b9626..7a2074f1a 100644 --- a/libgloss/mips/mti64_64.ld +++ b/libgloss/mips/mti64_64.ld @@ -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 = .; diff --git a/libgloss/mips/mti64_n32.ld b/libgloss/mips/mti64_n32.ld index 279571b2f..4003845e0 100644 --- a/libgloss/mips/mti64_n32.ld +++ b/libgloss/mips/mti64_n32.ld @@ -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 = .; diff --git a/libgloss/mips/regs.S b/libgloss/mips/regs.S index bdf933f13..e4b134307 100644 --- a/libgloss/mips/regs.S +++ b/libgloss/mips/regs.S @@ -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: */