rework structure
This commit is contained in:
		
							
								
								
									
										197
									
								
								benchmarks/coremark/tgc/core_portme.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								benchmarks/coremark/tgc/core_portme.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
 | 
			
		||||
Original Author: Shay Gal-on
 | 
			
		||||
*/
 | 
			
		||||
#include "coremark.h"
 | 
			
		||||
#include "core_portme.h"
 | 
			
		||||
//Read cycle CSR
 | 
			
		||||
unsigned long long _read_cycle()
 | 
			
		||||
{
 | 
			
		||||
    unsigned long long result;
 | 
			
		||||
    unsigned long lower;
 | 
			
		||||
    unsigned long upper1;
 | 
			
		||||
    unsigned long upper2;
 | 
			
		||||
 | 
			
		||||
    asm volatile (
 | 
			
		||||
        "repeat_cycle_%=: csrr %0, cycleh;\n"
 | 
			
		||||
        "        csrr %1, cycle;\n"
 | 
			
		||||
        "        csrr %2, cycleh;\n"
 | 
			
		||||
        "        bne %0, %2, repeat_cycle_%=;\n"
 | 
			
		||||
        : "=r" (upper1),"=r" (lower),"=r" (upper2)    // Outputs   : temp variable for load result
 | 
			
		||||
        :
 | 
			
		||||
        :
 | 
			
		||||
    );
 | 
			
		||||
    *(unsigned long *)(&result) = lower;
 | 
			
		||||
    *((unsigned long *)(&result)+1) = upper1;
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
volatile int tohost;
 | 
			
		||||
volatile int fromhost;
 | 
			
		||||
 | 
			
		||||
void exit(int n){
 | 
			
		||||
      tohost = 0x1;
 | 
			
		||||
      for (;;);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __libc_init_array (void) {
 | 
			
		||||
/*
 | 
			
		||||
    size_t count;
 | 
			
		||||
    size_t i;
 | 
			
		||||
    count = __preinit_array_end - __preinit_array_start;
 | 
			
		||||
    for (i = 0; i < count; i++)
 | 
			
		||||
        __preinit_array_start[i] ();
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_INIT_FINI
 | 
			
		||||
    _init ();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    count = __init_array_end - __init_array_start;
 | 
			
		||||
    for (i = 0; i < count; i++)
 | 
			
		||||
    __init_array_start[i] ();
 | 
			
		||||
*/
 | 
			
		||||
}
 | 
			
		||||
#if VALIDATION_RUN
 | 
			
		||||
volatile ee_s32 seed1_volatile = 0x3415;
 | 
			
		||||
volatile ee_s32 seed2_volatile = 0x3415;
 | 
			
		||||
volatile ee_s32 seed3_volatile = 0x66;
 | 
			
		||||
#endif
 | 
			
		||||
#if PERFORMANCE_RUN
 | 
			
		||||
volatile ee_s32 seed1_volatile = 0x0;
 | 
			
		||||
volatile ee_s32 seed2_volatile = 0x0;
 | 
			
		||||
volatile ee_s32 seed3_volatile = 0x66;
 | 
			
		||||
#endif
 | 
			
		||||
#if PROFILE_RUN
 | 
			
		||||
volatile ee_s32 seed1_volatile = 0x8;
 | 
			
		||||
volatile ee_s32 seed2_volatile = 0x8;
 | 
			
		||||
volatile ee_s32 seed3_volatile = 0x8;
 | 
			
		||||
#endif
 | 
			
		||||
volatile ee_s32 seed4_volatile = ITERATIONS;
 | 
			
		||||
volatile ee_s32 seed5_volatile = 0;
 | 
			
		||||
/* Porting : Timing functions
 | 
			
		||||
        How to capture time and convert to seconds must be ported to whatever is
 | 
			
		||||
   supported by the platform. e.g. Read value from on board RTC, read value from
 | 
			
		||||
   cpu clock cycles performance counter etc. Sample implementation for standard
 | 
			
		||||
   time.h and windows.h definitions included.
 | 
			
		||||
*/
 | 
			
		||||
CORETIMETYPE
 | 
			
		||||
barebones_clock()
 | 
			
		||||
{
 | 
			
		||||
    return (CORETIMETYPE)_read_cycle();
 | 
			
		||||
}
 | 
			
		||||
/* Define : TIMER_RES_DIVIDER
 | 
			
		||||
        Divider to trade off timer resolution and total time that can be
 | 
			
		||||
   measured.
 | 
			
		||||
 | 
			
		||||
        Use lower values to increase resolution, but make sure that overflow
 | 
			
		||||
   does not occur. If there are issues with the return value overflowing,
 | 
			
		||||
   increase this value.
 | 
			
		||||
        */
 | 
			
		||||
#define GETMYTIME(_t)              (*_t = barebones_clock())
 | 
			
		||||
#define MYTIMEDIFF(fin, ini)       ((fin) - (ini))
 | 
			
		||||
#define TIMER_RES_DIVIDER          1
 | 
			
		||||
#define SAMPLE_TIME_IMPLEMENTATION 1
 | 
			
		||||
#define EE_TICKS_PER_SEC           (CLOCKS_PER_SEC / TIMER_RES_DIVIDER)
 | 
			
		||||
 | 
			
		||||
/** Define Host specific (POSIX), or target specific global time variables. */
 | 
			
		||||
static CORETIMETYPE start_time_val, stop_time_val;
 | 
			
		||||
 | 
			
		||||
/* Function : start_time
 | 
			
		||||
        This function will be called right before starting the timed portion of
 | 
			
		||||
   the benchmark.
 | 
			
		||||
 | 
			
		||||
        Implementation may be capturing a system timer (as implemented in the
 | 
			
		||||
   example code) or zeroing some system parameters - e.g. setting the cpu clocks
 | 
			
		||||
   cycles to 0.
 | 
			
		||||
*/
 | 
			
		||||
void
 | 
			
		||||
start_time(void)
 | 
			
		||||
{
 | 
			
		||||
    GETMYTIME(&start_time_val);
 | 
			
		||||
}
 | 
			
		||||
/* Function : stop_time
 | 
			
		||||
        This function will be called right after ending the timed portion of the
 | 
			
		||||
   benchmark.
 | 
			
		||||
 | 
			
		||||
        Implementation may be capturing a system timer (as implemented in the
 | 
			
		||||
   example code) or other system parameters - e.g. reading the current value of
 | 
			
		||||
   cpu cycles counter.
 | 
			
		||||
*/
 | 
			
		||||
void
 | 
			
		||||
stop_time(void)
 | 
			
		||||
{
 | 
			
		||||
    GETMYTIME(&stop_time_val);
 | 
			
		||||
}
 | 
			
		||||
/* Function : get_time
 | 
			
		||||
        Return an abstract "ticks" number that signifies time on the system.
 | 
			
		||||
 | 
			
		||||
        Actual value returned may be cpu cycles, milliseconds or any other
 | 
			
		||||
   value, as long as it can be converted to seconds by <time_in_secs>. This
 | 
			
		||||
   methodology is taken to accomodate any hardware or simulated platform. The
 | 
			
		||||
   sample implementation returns millisecs by default, and the resolution is
 | 
			
		||||
   controlled by <TIMER_RES_DIVIDER>
 | 
			
		||||
*/
 | 
			
		||||
CORE_TICKS
 | 
			
		||||
get_time(void)
 | 
			
		||||
{
 | 
			
		||||
    CORE_TICKS elapsed
 | 
			
		||||
        = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
 | 
			
		||||
    return elapsed;
 | 
			
		||||
}
 | 
			
		||||
/* Function : time_in_secs
 | 
			
		||||
        Convert the value returned by get_time to seconds.
 | 
			
		||||
 | 
			
		||||
        The <secs_ret> type is used to accomodate systems with no support for
 | 
			
		||||
   floating point. Default implementation implemented by the EE_TICKS_PER_SEC
 | 
			
		||||
   macro above.
 | 
			
		||||
*/
 | 
			
		||||
secs_ret
 | 
			
		||||
time_in_secs(CORE_TICKS ticks)
 | 
			
		||||
{
 | 
			
		||||
    secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ee_u32 default_num_contexts = 1;
 | 
			
		||||
 | 
			
		||||
/* Function : portable_init
 | 
			
		||||
        Target specific initialization code
 | 
			
		||||
        Test for some common mistakes.
 | 
			
		||||
*/
 | 
			
		||||
void
 | 
			
		||||
portable_init(core_portable *p, int *argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    if (sizeof(ee_ptr_int) != sizeof(ee_u8 *))
 | 
			
		||||
    {
 | 
			
		||||
        ee_printf(
 | 
			
		||||
            "ERROR! Please define ee_ptr_int to a type that holds a "
 | 
			
		||||
            "pointer!\n");
 | 
			
		||||
    }
 | 
			
		||||
    if (sizeof(ee_u32) != 4)
 | 
			
		||||
    {
 | 
			
		||||
        ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
 | 
			
		||||
    }
 | 
			
		||||
    p->portable_id = 1;
 | 
			
		||||
}
 | 
			
		||||
/* Function : portable_fini
 | 
			
		||||
        Target specific final code
 | 
			
		||||
*/
 | 
			
		||||
void
 | 
			
		||||
portable_fini(core_portable *p)
 | 
			
		||||
{
 | 
			
		||||
    p->portable_id = 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										210
									
								
								benchmarks/coremark/tgc/core_portme.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								benchmarks/coremark/tgc/core_portme.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
 | 
			
		||||
Original Author: Shay Gal-on
 | 
			
		||||
*/
 | 
			
		||||
/* Topic : Description
 | 
			
		||||
        This file contains configuration constants required to execute on
 | 
			
		||||
   different platforms
 | 
			
		||||
*/
 | 
			
		||||
#ifndef CORE_PORTME_H
 | 
			
		||||
#define CORE_PORTME_H
 | 
			
		||||
/************************/
 | 
			
		||||
/* Data types and settings */
 | 
			
		||||
/************************/
 | 
			
		||||
/* Configuration : HAS_FLOAT
 | 
			
		||||
        Define to 1 if the platform supports floating point.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef HAS_FLOAT
 | 
			
		||||
#define HAS_FLOAT 0
 | 
			
		||||
#endif
 | 
			
		||||
/* Configuration : HAS_TIME_H
 | 
			
		||||
        Define to 1 if platform has the time.h header file,
 | 
			
		||||
        and implementation of functions thereof.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef HAS_TIME_H
 | 
			
		||||
#define HAS_TIME_H 0
 | 
			
		||||
#endif
 | 
			
		||||
/* Configuration : USE_CLOCK
 | 
			
		||||
        Define to 1 if platform has the time.h header file,
 | 
			
		||||
        and implementation of functions thereof.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef USE_CLOCK
 | 
			
		||||
#define USE_CLOCK 0
 | 
			
		||||
#endif
 | 
			
		||||
/* Configuration : HAS_STDIO
 | 
			
		||||
        Define to 1 if the platform has stdio.h.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef HAS_STDIO
 | 
			
		||||
#define HAS_STDIO 0
 | 
			
		||||
#endif
 | 
			
		||||
/* Configuration : HAS_PRINTF
 | 
			
		||||
        Define to 1 if the platform has stdio.h and implements the printf
 | 
			
		||||
   function.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef HAS_PRINTF
 | 
			
		||||
#define HAS_PRINTF 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
 | 
			
		||||
        Initialize these strings per platform
 | 
			
		||||
*/
 | 
			
		||||
#ifndef COMPILER_VERSION
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
#define COMPILER_VERSION "GCC"__VERSION__
 | 
			
		||||
#else
 | 
			
		||||
#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)"
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef COMPILER_FLAGS
 | 
			
		||||
#define COMPILER_FLAGS \
 | 
			
		||||
    FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef MEM_LOCATION
 | 
			
		||||
#define MEM_LOCATION "STACK"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Data Types :
 | 
			
		||||
        To avoid compiler issues, define the data types that need ot be used for
 | 
			
		||||
   8b, 16b and 32b in <core_portme.h>.
 | 
			
		||||
 | 
			
		||||
        *Imprtant* :
 | 
			
		||||
        ee_ptr_int needs to be the data type used to hold pointers, otherwise
 | 
			
		||||
   coremark may fail!!!
 | 
			
		||||
*/
 | 
			
		||||
typedef signed short   ee_s16;
 | 
			
		||||
typedef unsigned short ee_u16;
 | 
			
		||||
typedef signed int     ee_s32;
 | 
			
		||||
typedef double         ee_f32;
 | 
			
		||||
typedef unsigned char  ee_u8;
 | 
			
		||||
typedef unsigned int   ee_u32;
 | 
			
		||||
typedef ee_u32         ee_ptr_int;
 | 
			
		||||
typedef ee_u32         ee_size_t;
 | 
			
		||||
#define NULL ((void *)0)
 | 
			
		||||
/* align_mem :
 | 
			
		||||
        This macro is used to align an offset to point to a 32b value. It is
 | 
			
		||||
   used in the Matrix algorithm to initialize the input memory blocks.
 | 
			
		||||
*/
 | 
			
		||||
#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3))
 | 
			
		||||
 | 
			
		||||
/* Configuration : CORE_TICKS
 | 
			
		||||
        Define type of return from the timing functions.
 | 
			
		||||
 */
 | 
			
		||||
#define CORETIMETYPE ee_u32
 | 
			
		||||
typedef ee_u32 CORE_TICKS;
 | 
			
		||||
 | 
			
		||||
/* Configuration : SEED_METHOD
 | 
			
		||||
        Defines method to get seed values that cannot be computed at compile
 | 
			
		||||
   time.
 | 
			
		||||
 | 
			
		||||
        Valid values :
 | 
			
		||||
        SEED_ARG - from command line.
 | 
			
		||||
        SEED_FUNC - from a system function.
 | 
			
		||||
        SEED_VOLATILE - from volatile variables.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef SEED_METHOD
 | 
			
		||||
#define SEED_METHOD SEED_VOLATILE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Configuration : MEM_METHOD
 | 
			
		||||
        Defines method to get a block of memry.
 | 
			
		||||
 | 
			
		||||
        Valid values :
 | 
			
		||||
        MEM_MALLOC - for platforms that implement malloc and have malloc.h.
 | 
			
		||||
        MEM_STATIC - to use a static memory array.
 | 
			
		||||
        MEM_STACK - to allocate the data block on the stack (NYI).
 | 
			
		||||
*/
 | 
			
		||||
#ifndef MEM_METHOD
 | 
			
		||||
#define MEM_METHOD MEM_STACK
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Configuration : MULTITHREAD
 | 
			
		||||
        Define for parallel execution
 | 
			
		||||
 | 
			
		||||
        Valid values :
 | 
			
		||||
        1 - only one context (default).
 | 
			
		||||
        N>1 - will execute N copies in parallel.
 | 
			
		||||
 | 
			
		||||
        Note :
 | 
			
		||||
        If this flag is defined to more then 1, an implementation for launching
 | 
			
		||||
   parallel contexts must be defined.
 | 
			
		||||
 | 
			
		||||
        Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK>
 | 
			
		||||
   to enable them.
 | 
			
		||||
 | 
			
		||||
        It is valid to have a different implementation of <core_start_parallel>
 | 
			
		||||
   and <core_end_parallel> in <core_portme.c>, to fit a particular architecture.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef MULTITHREAD
 | 
			
		||||
#define MULTITHREAD 1
 | 
			
		||||
#define USE_PTHREAD 0
 | 
			
		||||
#define USE_FORK    0
 | 
			
		||||
#define USE_SOCKET  0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Configuration : MAIN_HAS_NOARGC
 | 
			
		||||
        Needed if platform does not support getting arguments to main.
 | 
			
		||||
 | 
			
		||||
        Valid values :
 | 
			
		||||
        0 - argc/argv to main is supported
 | 
			
		||||
        1 - argc/argv to main is not supported
 | 
			
		||||
 | 
			
		||||
        Note :
 | 
			
		||||
        This flag only matters if MULTITHREAD has been defined to a value
 | 
			
		||||
   greater then 1.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef MAIN_HAS_NOARGC
 | 
			
		||||
#define MAIN_HAS_NOARGC 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Configuration : MAIN_HAS_NORETURN
 | 
			
		||||
        Needed if platform does not support returning a value from main.
 | 
			
		||||
 | 
			
		||||
        Valid values :
 | 
			
		||||
        0 - main returns an int, and return value will be 0.
 | 
			
		||||
        1 - platform does not support returning a value from main
 | 
			
		||||
*/
 | 
			
		||||
#ifndef MAIN_HAS_NORETURN
 | 
			
		||||
#define MAIN_HAS_NORETURN 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Variable : default_num_contexts
 | 
			
		||||
        Not used for this simple port, must cintain the value 1.
 | 
			
		||||
*/
 | 
			
		||||
extern ee_u32 default_num_contexts;
 | 
			
		||||
 | 
			
		||||
typedef struct CORE_PORTABLE_S
 | 
			
		||||
{
 | 
			
		||||
    ee_u8 portable_id;
 | 
			
		||||
} core_portable;
 | 
			
		||||
 | 
			
		||||
/* target specific init/fini */
 | 
			
		||||
void portable_init(core_portable *p, int *argc, char *argv[]);
 | 
			
		||||
void portable_fini(core_portable *p);
 | 
			
		||||
 | 
			
		||||
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) \
 | 
			
		||||
    && !defined(VALIDATION_RUN)
 | 
			
		||||
#if (TOTAL_DATA_SIZE == 1200)
 | 
			
		||||
#define PROFILE_RUN 1
 | 
			
		||||
#elif (TOTAL_DATA_SIZE == 2000)
 | 
			
		||||
#define PERFORMANCE_RUN 1
 | 
			
		||||
#else
 | 
			
		||||
#define VALIDATION_RUN 1
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int ee_printf(const char *fmt, ...);
 | 
			
		||||
 | 
			
		||||
#endif /* CORE_PORTME_H */
 | 
			
		||||
							
								
								
									
										94
									
								
								benchmarks/coremark/tgc/core_portme.mak
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										94
									
								
								benchmarks/coremark/tgc/core_portme.mak
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
 | 
			
		||||
#
 | 
			
		||||
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
# you may not use this file except in compliance with the License.
 | 
			
		||||
# You may obtain a copy of the License at
 | 
			
		||||
#
 | 
			
		||||
#    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
#
 | 
			
		||||
# Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
# See the License for the specific language governing permissions and
 | 
			
		||||
# limitations under the License.
 | 
			
		||||
# 
 | 
			
		||||
# Original Author: Shay Gal-on
 | 
			
		||||
 | 
			
		||||
#File : core_portme.mak
 | 
			
		||||
ISA?=imc
 | 
			
		||||
RISCV_ARCH:=rv32$(ISA)
 | 
			
		||||
RISCV_ABI:=ilp32
 | 
			
		||||
 | 
			
		||||
# Flag : OUTFLAG
 | 
			
		||||
#	Use this flag to define how to to get an executable (e.g -o)
 | 
			
		||||
OUTFLAG= -o
 | 
			
		||||
# Flag : CC
 | 
			
		||||
#	Use this flag to define compiler to use
 | 
			
		||||
CC 		= riscv32-unknown-elf-gcc
 | 
			
		||||
# Flag : LD
 | 
			
		||||
#	Use this flag to define compiler to use
 | 
			
		||||
LD		= riscv32-unknown-elf-gcc
 | 
			
		||||
# Flag : AS
 | 
			
		||||
#	Use this flag to define compiler to use
 | 
			
		||||
AS		= riscv32-unknown-elf-as
 | 
			
		||||
# Flag : CFLAGS
 | 
			
		||||
#	Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags"
 | 
			
		||||
PORT_CFLAGS = -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -O3 -DCLOCKS_PER_SEC=10000000 -nostdlib -nostartfiles -nodefaultlibs \
 | 
			
		||||
 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -flto
 | 
			
		||||
FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)"
 | 
			
		||||
CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -I. -DFLAGS_STR=\"$(FLAGS_STR)\" 
 | 
			
		||||
#Flag : LFLAGS_END
 | 
			
		||||
#	Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts). 
 | 
			
		||||
#	Note : On certain platforms, the default clock_gettime implementation is supported but requires linking of librt.
 | 
			
		||||
SEPARATE_COMPILE=1
 | 
			
		||||
# Flag : SEPARATE_COMPILE
 | 
			
		||||
# You must also define below how to create an object file, and how to link.
 | 
			
		||||
OBJOUT 	= -o
 | 
			
		||||
LFLAGS 	= 
 | 
			
		||||
#--specs=nano.specs -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) 
 | 
			
		||||
ASFLAGS =
 | 
			
		||||
OFLAG 	= -o
 | 
			
		||||
COUT 	= -c
 | 
			
		||||
 | 
			
		||||
LFLAGS_END = 
 | 
			
		||||
# Flag : PORT_SRCS
 | 
			
		||||
# 	Port specific source files can be added here
 | 
			
		||||
#	You may also need cvt.c if the fcvt functions are not provided as intrinsics by your compiler!
 | 
			
		||||
PORT_SRCS = $(PORT_DIR)/core_portme.c $(PORT_DIR)/ee_printf.c
 | 
			
		||||
vpath %.c $(PORT_DIR)
 | 
			
		||||
vpath %.s $(PORT_DIR)
 | 
			
		||||
PORT_OBJS = core_portme.o ee_printf.o
 | 
			
		||||
# Flag : LOAD
 | 
			
		||||
#	For a simple port, we assume self hosted compile and run, no load needed.
 | 
			
		||||
 | 
			
		||||
# Flag : RUN
 | 
			
		||||
#	For a simple port, we assume self hosted compile and run, simple invocation of the executable
 | 
			
		||||
 | 
			
		||||
LOAD = echo ""
 | 
			
		||||
RUN = echo ""
 | 
			
		||||
 | 
			
		||||
OEXT = .o
 | 
			
		||||
EXE = .elf
 | 
			
		||||
 | 
			
		||||
$(OPATH)$(PORT_DIR)/%$(OEXT) : %.c
 | 
			
		||||
	$(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@
 | 
			
		||||
 | 
			
		||||
$(OPATH)%$(OEXT) : %.c
 | 
			
		||||
	$(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@
 | 
			
		||||
 | 
			
		||||
$(OPATH)$(PORT_DIR)/%$(OEXT) : %.s
 | 
			
		||||
	$(AS) $(ASFLAGS) $< $(OBJOUT) $@
 | 
			
		||||
 | 
			
		||||
# Target : port_pre% and port_post%
 | 
			
		||||
# For the purpose of this simple port, no pre or post steps needed.
 | 
			
		||||
 | 
			
		||||
.PHONY : port_prebuild port_postbuild port_prerun port_postrun port_preload port_postload
 | 
			
		||||
port_pre% port_post% : 
 | 
			
		||||
 | 
			
		||||
# FLAG : OPATH
 | 
			
		||||
# Path to the output folder. Default - current folder.
 | 
			
		||||
OPATH = ./
 | 
			
		||||
MKDIR = mkdir -p
 | 
			
		||||
 | 
			
		||||
dist-clean: clean
 | 
			
		||||
	rm -f *.o
 | 
			
		||||
							
								
								
									
										127
									
								
								benchmarks/coremark/tgc/cvt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								benchmarks/coremark/tgc/cvt.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#define CVTBUFSIZE 80
 | 
			
		||||
static char CVTBUF[CVTBUFSIZE];
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag)
 | 
			
		||||
{
 | 
			
		||||
    int    r2;
 | 
			
		||||
    double fi, fj;
 | 
			
		||||
    char * p, *p1;
 | 
			
		||||
 | 
			
		||||
    if (ndigits < 0)
 | 
			
		||||
        ndigits = 0;
 | 
			
		||||
    if (ndigits >= CVTBUFSIZE - 1)
 | 
			
		||||
        ndigits = CVTBUFSIZE - 2;
 | 
			
		||||
    r2    = 0;
 | 
			
		||||
    *sign = 0;
 | 
			
		||||
    p     = &buf[0];
 | 
			
		||||
    if (arg < 0)
 | 
			
		||||
    {
 | 
			
		||||
        *sign = 1;
 | 
			
		||||
        arg   = -arg;
 | 
			
		||||
    }
 | 
			
		||||
    arg = modf(arg, &fi);
 | 
			
		||||
    p1  = &buf[CVTBUFSIZE];
 | 
			
		||||
 | 
			
		||||
    if (fi != 0)
 | 
			
		||||
    {
 | 
			
		||||
        p1 = &buf[CVTBUFSIZE];
 | 
			
		||||
        while (fi != 0)
 | 
			
		||||
        {
 | 
			
		||||
            fj    = modf(fi / 10, &fi);
 | 
			
		||||
            *--p1 = (int)((fj + .03) * 10) + '0';
 | 
			
		||||
            r2++;
 | 
			
		||||
        }
 | 
			
		||||
        while (p1 < &buf[CVTBUFSIZE])
 | 
			
		||||
            *p++ = *p1++;
 | 
			
		||||
    }
 | 
			
		||||
    else if (arg > 0)
 | 
			
		||||
    {
 | 
			
		||||
        while ((fj = arg * 10) < 1)
 | 
			
		||||
        {
 | 
			
		||||
            arg = fj;
 | 
			
		||||
            r2--;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    p1 = &buf[ndigits];
 | 
			
		||||
    if (eflag == 0)
 | 
			
		||||
        p1 += r2;
 | 
			
		||||
    *decpt = r2;
 | 
			
		||||
    if (p1 < &buf[0])
 | 
			
		||||
    {
 | 
			
		||||
        buf[0] = '\0';
 | 
			
		||||
        return buf;
 | 
			
		||||
    }
 | 
			
		||||
    while (p <= p1 && p < &buf[CVTBUFSIZE])
 | 
			
		||||
    {
 | 
			
		||||
        arg *= 10;
 | 
			
		||||
        arg  = modf(arg, &fj);
 | 
			
		||||
        *p++ = (int)fj + '0';
 | 
			
		||||
    }
 | 
			
		||||
    if (p1 >= &buf[CVTBUFSIZE])
 | 
			
		||||
    {
 | 
			
		||||
        buf[CVTBUFSIZE - 1] = '\0';
 | 
			
		||||
        return buf;
 | 
			
		||||
    }
 | 
			
		||||
    p = p1;
 | 
			
		||||
    *p1 += 5;
 | 
			
		||||
    while (*p1 > '9')
 | 
			
		||||
    {
 | 
			
		||||
        *p1 = '0';
 | 
			
		||||
        if (p1 > buf)
 | 
			
		||||
            ++*--p1;
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            *p1 = '1';
 | 
			
		||||
            (*decpt)++;
 | 
			
		||||
            if (eflag == 0)
 | 
			
		||||
            {
 | 
			
		||||
                if (p > buf)
 | 
			
		||||
                    *p = '0';
 | 
			
		||||
                p++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    *p = '\0';
 | 
			
		||||
    return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
ecvt(double arg, int ndigits, int *decpt, int *sign)
 | 
			
		||||
{
 | 
			
		||||
    return cvt(arg, ndigits, decpt, sign, CVTBUF, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf)
 | 
			
		||||
{
 | 
			
		||||
    return cvt(arg, ndigits, decpt, sign, buf, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
fcvt(double arg, int ndigits, int *decpt, int *sign)
 | 
			
		||||
{
 | 
			
		||||
    return cvt(arg, ndigits, decpt, sign, CVTBUF, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf)
 | 
			
		||||
{
 | 
			
		||||
    return cvt(arg, ndigits, decpt, sign, buf, 0);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										701
									
								
								benchmarks/coremark/tgc/ee_printf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										701
									
								
								benchmarks/coremark/tgc/ee_printf.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,701 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <coremark.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
#define ZEROPAD   (1 << 0) /* Pad with zero */
 | 
			
		||||
#define SIGN      (1 << 1) /* Unsigned/signed long */
 | 
			
		||||
#define PLUS      (1 << 2) /* Show plus */
 | 
			
		||||
#define SPACE     (1 << 3) /* Spacer */
 | 
			
		||||
#define LEFT      (1 << 4) /* Left justified */
 | 
			
		||||
#define HEX_PREP  (1 << 5) /* 0x */
 | 
			
		||||
#define UPPERCASE (1 << 6) /* 'ABCDEF' */
 | 
			
		||||
 | 
			
		||||
#define is_digit(c) ((c) >= '0' && (c) <= '9')
 | 
			
		||||
 | 
			
		||||
static char *    digits       = "0123456789abcdefghijklmnopqrstuvwxyz";
 | 
			
		||||
static char *    upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 | 
			
		||||
static ee_size_t strnlen(const char *s, ee_size_t count);
 | 
			
		||||
 | 
			
		||||
static ee_size_t
 | 
			
		||||
strnlen(const char *s, ee_size_t count)
 | 
			
		||||
{
 | 
			
		||||
    const char *sc;
 | 
			
		||||
    for (sc = s; *sc != '\0' && count--; ++sc)
 | 
			
		||||
        ;
 | 
			
		||||
    return sc - s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
skip_atoi(const char **s)
 | 
			
		||||
{
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    while (is_digit(**s))
 | 
			
		||||
        i = i * 10 + *((*s)++) - '0';
 | 
			
		||||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
number(char *str, long num, int base, int size, int precision, int type)
 | 
			
		||||
{
 | 
			
		||||
    char  c, sign, tmp[66];
 | 
			
		||||
    char *dig = digits;
 | 
			
		||||
    int   i;
 | 
			
		||||
 | 
			
		||||
    if (type & UPPERCASE)
 | 
			
		||||
        dig = upper_digits;
 | 
			
		||||
    if (type & LEFT)
 | 
			
		||||
        type &= ~ZEROPAD;
 | 
			
		||||
    if (base < 2 || base > 36)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    c    = (type & ZEROPAD) ? '0' : ' ';
 | 
			
		||||
    sign = 0;
 | 
			
		||||
    if (type & SIGN)
 | 
			
		||||
    {
 | 
			
		||||
        if (num < 0)
 | 
			
		||||
        {
 | 
			
		||||
            sign = '-';
 | 
			
		||||
            num  = -num;
 | 
			
		||||
            size--;
 | 
			
		||||
        }
 | 
			
		||||
        else if (type & PLUS)
 | 
			
		||||
        {
 | 
			
		||||
            sign = '+';
 | 
			
		||||
            size--;
 | 
			
		||||
        }
 | 
			
		||||
        else if (type & SPACE)
 | 
			
		||||
        {
 | 
			
		||||
            sign = ' ';
 | 
			
		||||
            size--;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (type & HEX_PREP)
 | 
			
		||||
    {
 | 
			
		||||
        if (base == 16)
 | 
			
		||||
            size -= 2;
 | 
			
		||||
        else if (base == 8)
 | 
			
		||||
            size--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    i = 0;
 | 
			
		||||
 | 
			
		||||
    if (num == 0)
 | 
			
		||||
        tmp[i++] = '0';
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        while (num != 0)
 | 
			
		||||
        {
 | 
			
		||||
            tmp[i++] = dig[((unsigned long)num) % (unsigned)base];
 | 
			
		||||
            num      = ((unsigned long)num) / (unsigned)base;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (i > precision)
 | 
			
		||||
        precision = i;
 | 
			
		||||
    size -= precision;
 | 
			
		||||
    if (!(type & (ZEROPAD | LEFT)))
 | 
			
		||||
        while (size-- > 0)
 | 
			
		||||
            *str++ = ' ';
 | 
			
		||||
    if (sign)
 | 
			
		||||
        *str++ = sign;
 | 
			
		||||
 | 
			
		||||
    if (type & HEX_PREP)
 | 
			
		||||
    {
 | 
			
		||||
        if (base == 8)
 | 
			
		||||
            *str++ = '0';
 | 
			
		||||
        else if (base == 16)
 | 
			
		||||
        {
 | 
			
		||||
            *str++ = '0';
 | 
			
		||||
            *str++ = digits[33];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!(type & LEFT))
 | 
			
		||||
        while (size-- > 0)
 | 
			
		||||
            *str++ = c;
 | 
			
		||||
    while (i < precision--)
 | 
			
		||||
        *str++ = '0';
 | 
			
		||||
    while (i-- > 0)
 | 
			
		||||
        *str++ = tmp[i];
 | 
			
		||||
    while (size-- > 0)
 | 
			
		||||
        *str++ = ' ';
 | 
			
		||||
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
eaddr(char *str, unsigned char *addr, int size, int precision, int type)
 | 
			
		||||
{
 | 
			
		||||
    char  tmp[24];
 | 
			
		||||
    char *dig = digits;
 | 
			
		||||
    int   i, len;
 | 
			
		||||
 | 
			
		||||
    if (type & UPPERCASE)
 | 
			
		||||
        dig = upper_digits;
 | 
			
		||||
    len = 0;
 | 
			
		||||
    for (i = 0; i < 6; i++)
 | 
			
		||||
    {
 | 
			
		||||
        if (i != 0)
 | 
			
		||||
            tmp[len++] = ':';
 | 
			
		||||
        tmp[len++] = dig[addr[i] >> 4];
 | 
			
		||||
        tmp[len++] = dig[addr[i] & 0x0F];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!(type & LEFT))
 | 
			
		||||
        while (len < size--)
 | 
			
		||||
            *str++ = ' ';
 | 
			
		||||
    for (i = 0; i < len; ++i)
 | 
			
		||||
        *str++ = tmp[i];
 | 
			
		||||
    while (len < size--)
 | 
			
		||||
        *str++ = ' ';
 | 
			
		||||
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
iaddr(char *str, unsigned char *addr, int size, int precision, int type)
 | 
			
		||||
{
 | 
			
		||||
    char tmp[24];
 | 
			
		||||
    int  i, n, len;
 | 
			
		||||
 | 
			
		||||
    len = 0;
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
    {
 | 
			
		||||
        if (i != 0)
 | 
			
		||||
            tmp[len++] = '.';
 | 
			
		||||
        n = addr[i];
 | 
			
		||||
 | 
			
		||||
        if (n == 0)
 | 
			
		||||
            tmp[len++] = digits[0];
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (n >= 100)
 | 
			
		||||
            {
 | 
			
		||||
                tmp[len++] = digits[n / 100];
 | 
			
		||||
                n          = n % 100;
 | 
			
		||||
                tmp[len++] = digits[n / 10];
 | 
			
		||||
                n          = n % 10;
 | 
			
		||||
            }
 | 
			
		||||
            else if (n >= 10)
 | 
			
		||||
            {
 | 
			
		||||
                tmp[len++] = digits[n / 10];
 | 
			
		||||
                n          = n % 10;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tmp[len++] = digits[n];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!(type & LEFT))
 | 
			
		||||
        while (len < size--)
 | 
			
		||||
            *str++ = ' ';
 | 
			
		||||
    for (i = 0; i < len; ++i)
 | 
			
		||||
        *str++ = tmp[i];
 | 
			
		||||
    while (len < size--)
 | 
			
		||||
        *str++ = ' ';
 | 
			
		||||
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if HAS_FLOAT
 | 
			
		||||
 | 
			
		||||
char *      ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
 | 
			
		||||
char *      fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
 | 
			
		||||
static void ee_bufcpy(char *d, char *s, int count);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ee_bufcpy(char *pd, char *ps, int count)
 | 
			
		||||
{
 | 
			
		||||
    char *pe = ps + count;
 | 
			
		||||
    while (ps != pe)
 | 
			
		||||
        *pd++ = *ps++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
parse_float(double value, char *buffer, char fmt, int precision)
 | 
			
		||||
{
 | 
			
		||||
    int   decpt, sign, exp, pos;
 | 
			
		||||
    char *digits = NULL;
 | 
			
		||||
    char  cvtbuf[80];
 | 
			
		||||
    int   capexp = 0;
 | 
			
		||||
    int   magnitude;
 | 
			
		||||
 | 
			
		||||
    if (fmt == 'G' || fmt == 'E')
 | 
			
		||||
    {
 | 
			
		||||
        capexp = 1;
 | 
			
		||||
        fmt += 'a' - 'A';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (fmt == 'g')
 | 
			
		||||
    {
 | 
			
		||||
        digits    = ecvtbuf(value, precision, &decpt, &sign, cvtbuf);
 | 
			
		||||
        magnitude = decpt - 1;
 | 
			
		||||
        if (magnitude < -4 || magnitude > precision - 1)
 | 
			
		||||
        {
 | 
			
		||||
            fmt = 'e';
 | 
			
		||||
            precision -= 1;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            fmt = 'f';
 | 
			
		||||
            precision -= decpt;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (fmt == 'e')
 | 
			
		||||
    {
 | 
			
		||||
        digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf);
 | 
			
		||||
 | 
			
		||||
        if (sign)
 | 
			
		||||
            *buffer++ = '-';
 | 
			
		||||
        *buffer++ = *digits;
 | 
			
		||||
        if (precision > 0)
 | 
			
		||||
            *buffer++ = '.';
 | 
			
		||||
        ee_bufcpy(buffer, digits + 1, precision);
 | 
			
		||||
        buffer += precision;
 | 
			
		||||
        *buffer++ = capexp ? 'E' : 'e';
 | 
			
		||||
 | 
			
		||||
        if (decpt == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (value == 0.0)
 | 
			
		||||
                exp = 0;
 | 
			
		||||
            else
 | 
			
		||||
                exp = -1;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            exp = decpt - 1;
 | 
			
		||||
 | 
			
		||||
        if (exp < 0)
 | 
			
		||||
        {
 | 
			
		||||
            *buffer++ = '-';
 | 
			
		||||
            exp       = -exp;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            *buffer++ = '+';
 | 
			
		||||
 | 
			
		||||
        buffer[2] = (exp % 10) + '0';
 | 
			
		||||
        exp       = exp / 10;
 | 
			
		||||
        buffer[1] = (exp % 10) + '0';
 | 
			
		||||
        exp       = exp / 10;
 | 
			
		||||
        buffer[0] = (exp % 10) + '0';
 | 
			
		||||
        buffer += 3;
 | 
			
		||||
    }
 | 
			
		||||
    else if (fmt == 'f')
 | 
			
		||||
    {
 | 
			
		||||
        digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf);
 | 
			
		||||
        if (sign)
 | 
			
		||||
            *buffer++ = '-';
 | 
			
		||||
        if (*digits)
 | 
			
		||||
        {
 | 
			
		||||
            if (decpt <= 0)
 | 
			
		||||
            {
 | 
			
		||||
                *buffer++ = '0';
 | 
			
		||||
                *buffer++ = '.';
 | 
			
		||||
                for (pos = 0; pos < -decpt; pos++)
 | 
			
		||||
                    *buffer++ = '0';
 | 
			
		||||
                while (*digits)
 | 
			
		||||
                    *buffer++ = *digits++;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                pos = 0;
 | 
			
		||||
                while (*digits)
 | 
			
		||||
                {
 | 
			
		||||
                    if (pos++ == decpt)
 | 
			
		||||
                        *buffer++ = '.';
 | 
			
		||||
                    *buffer++ = *digits++;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            *buffer++ = '0';
 | 
			
		||||
            if (precision > 0)
 | 
			
		||||
            {
 | 
			
		||||
                *buffer++ = '.';
 | 
			
		||||
                for (pos = 0; pos < precision; pos++)
 | 
			
		||||
                    *buffer++ = '0';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *buffer = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
decimal_point(char *buffer)
 | 
			
		||||
{
 | 
			
		||||
    while (*buffer)
 | 
			
		||||
    {
 | 
			
		||||
        if (*buffer == '.')
 | 
			
		||||
            return;
 | 
			
		||||
        if (*buffer == 'e' || *buffer == 'E')
 | 
			
		||||
            break;
 | 
			
		||||
        buffer++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (*buffer)
 | 
			
		||||
    {
 | 
			
		||||
        int n = strnlen(buffer, 256);
 | 
			
		||||
        while (n > 0)
 | 
			
		||||
        {
 | 
			
		||||
            buffer[n + 1] = buffer[n];
 | 
			
		||||
            n--;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        *buffer = '.';
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        *buffer++ = '.';
 | 
			
		||||
        *buffer   = '\0';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cropzeros(char *buffer)
 | 
			
		||||
{
 | 
			
		||||
    char *stop;
 | 
			
		||||
 | 
			
		||||
    while (*buffer && *buffer != '.')
 | 
			
		||||
        buffer++;
 | 
			
		||||
    if (*buffer++)
 | 
			
		||||
    {
 | 
			
		||||
        while (*buffer && *buffer != 'e' && *buffer != 'E')
 | 
			
		||||
            buffer++;
 | 
			
		||||
        stop = buffer--;
 | 
			
		||||
        while (*buffer == '0')
 | 
			
		||||
            buffer--;
 | 
			
		||||
        if (*buffer == '.')
 | 
			
		||||
            buffer--;
 | 
			
		||||
        while (buffer != stop)
 | 
			
		||||
            *++buffer = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
flt(char *str, double num, int size, int precision, char fmt, int flags)
 | 
			
		||||
{
 | 
			
		||||
    char tmp[80];
 | 
			
		||||
    char c, sign;
 | 
			
		||||
    int  n, i;
 | 
			
		||||
 | 
			
		||||
    // Left align means no zero padding
 | 
			
		||||
    if (flags & LEFT)
 | 
			
		||||
        flags &= ~ZEROPAD;
 | 
			
		||||
 | 
			
		||||
    // Determine padding and sign char
 | 
			
		||||
    c    = (flags & ZEROPAD) ? '0' : ' ';
 | 
			
		||||
    sign = 0;
 | 
			
		||||
    if (flags & SIGN)
 | 
			
		||||
    {
 | 
			
		||||
        if (num < 0.0)
 | 
			
		||||
        {
 | 
			
		||||
            sign = '-';
 | 
			
		||||
            num  = -num;
 | 
			
		||||
            size--;
 | 
			
		||||
        }
 | 
			
		||||
        else if (flags & PLUS)
 | 
			
		||||
        {
 | 
			
		||||
            sign = '+';
 | 
			
		||||
            size--;
 | 
			
		||||
        }
 | 
			
		||||
        else if (flags & SPACE)
 | 
			
		||||
        {
 | 
			
		||||
            sign = ' ';
 | 
			
		||||
            size--;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Compute the precision value
 | 
			
		||||
    if (precision < 0)
 | 
			
		||||
        precision = 6; // Default precision: 6
 | 
			
		||||
 | 
			
		||||
    // Convert floating point number to text
 | 
			
		||||
    parse_float(num, tmp, fmt, precision);
 | 
			
		||||
 | 
			
		||||
    if ((flags & HEX_PREP) && precision == 0)
 | 
			
		||||
        decimal_point(tmp);
 | 
			
		||||
    if (fmt == 'g' && !(flags & HEX_PREP))
 | 
			
		||||
        cropzeros(tmp);
 | 
			
		||||
 | 
			
		||||
    n = strnlen(tmp, 256);
 | 
			
		||||
 | 
			
		||||
    // Output number with alignment and padding
 | 
			
		||||
    size -= n;
 | 
			
		||||
    if (!(flags & (ZEROPAD | LEFT)))
 | 
			
		||||
        while (size-- > 0)
 | 
			
		||||
            *str++ = ' ';
 | 
			
		||||
    if (sign)
 | 
			
		||||
        *str++ = sign;
 | 
			
		||||
    if (!(flags & LEFT))
 | 
			
		||||
        while (size-- > 0)
 | 
			
		||||
            *str++ = c;
 | 
			
		||||
    for (i = 0; i < n; i++)
 | 
			
		||||
        *str++ = tmp[i];
 | 
			
		||||
    while (size-- > 0)
 | 
			
		||||
        *str++ = ' ';
 | 
			
		||||
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
ee_vsprintf(char *buf, const char *fmt, va_list args)
 | 
			
		||||
{
 | 
			
		||||
    int           len;
 | 
			
		||||
    unsigned long num;
 | 
			
		||||
    int           i, base;
 | 
			
		||||
    char *        str;
 | 
			
		||||
    char *        s;
 | 
			
		||||
 | 
			
		||||
    int flags; // Flags to number()
 | 
			
		||||
 | 
			
		||||
    int field_width; // Width of output field
 | 
			
		||||
    int precision;   // Min. # of digits for integers; max number of chars for
 | 
			
		||||
                     // from string
 | 
			
		||||
    int qualifier;   // 'h', 'l', or 'L' for integer fields
 | 
			
		||||
 | 
			
		||||
    for (str = buf; *fmt; fmt++)
 | 
			
		||||
    {
 | 
			
		||||
        if (*fmt != '%')
 | 
			
		||||
        {
 | 
			
		||||
            *str++ = *fmt;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Process flags
 | 
			
		||||
        flags = 0;
 | 
			
		||||
    repeat:
 | 
			
		||||
        fmt++; // This also skips first '%'
 | 
			
		||||
        switch (*fmt)
 | 
			
		||||
        {
 | 
			
		||||
            case '-':
 | 
			
		||||
                flags |= LEFT;
 | 
			
		||||
                goto repeat;
 | 
			
		||||
            case '+':
 | 
			
		||||
                flags |= PLUS;
 | 
			
		||||
                goto repeat;
 | 
			
		||||
            case ' ':
 | 
			
		||||
                flags |= SPACE;
 | 
			
		||||
                goto repeat;
 | 
			
		||||
            case '#':
 | 
			
		||||
                flags |= HEX_PREP;
 | 
			
		||||
                goto repeat;
 | 
			
		||||
            case '0':
 | 
			
		||||
                flags |= ZEROPAD;
 | 
			
		||||
                goto repeat;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get field width
 | 
			
		||||
        field_width = -1;
 | 
			
		||||
        if (is_digit(*fmt))
 | 
			
		||||
            field_width = skip_atoi(&fmt);
 | 
			
		||||
        else if (*fmt == '*')
 | 
			
		||||
        {
 | 
			
		||||
            fmt++;
 | 
			
		||||
            field_width = va_arg(args, int);
 | 
			
		||||
            if (field_width < 0)
 | 
			
		||||
            {
 | 
			
		||||
                field_width = -field_width;
 | 
			
		||||
                flags |= LEFT;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get the precision
 | 
			
		||||
        precision = -1;
 | 
			
		||||
        if (*fmt == '.')
 | 
			
		||||
        {
 | 
			
		||||
            ++fmt;
 | 
			
		||||
            if (is_digit(*fmt))
 | 
			
		||||
                precision = skip_atoi(&fmt);
 | 
			
		||||
            else if (*fmt == '*')
 | 
			
		||||
            {
 | 
			
		||||
                ++fmt;
 | 
			
		||||
                precision = va_arg(args, int);
 | 
			
		||||
            }
 | 
			
		||||
            if (precision < 0)
 | 
			
		||||
                precision = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get the conversion qualifier
 | 
			
		||||
        qualifier = -1;
 | 
			
		||||
        if (*fmt == 'l' || *fmt == 'L')
 | 
			
		||||
        {
 | 
			
		||||
            qualifier = *fmt;
 | 
			
		||||
            fmt++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Default base
 | 
			
		||||
        base = 10;
 | 
			
		||||
 | 
			
		||||
        switch (*fmt)
 | 
			
		||||
        {
 | 
			
		||||
            case 'c':
 | 
			
		||||
                if (!(flags & LEFT))
 | 
			
		||||
                    while (--field_width > 0)
 | 
			
		||||
                        *str++ = ' ';
 | 
			
		||||
                *str++ = (unsigned char)va_arg(args, int);
 | 
			
		||||
                while (--field_width > 0)
 | 
			
		||||
                    *str++ = ' ';
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            case 's':
 | 
			
		||||
                s = va_arg(args, char *);
 | 
			
		||||
                if (!s)
 | 
			
		||||
                    s = "<NULL>";
 | 
			
		||||
                len = strnlen(s, precision);
 | 
			
		||||
                if (!(flags & LEFT))
 | 
			
		||||
                    while (len < field_width--)
 | 
			
		||||
                        *str++ = ' ';
 | 
			
		||||
                for (i = 0; i < len; ++i)
 | 
			
		||||
                    *str++ = *s++;
 | 
			
		||||
                while (len < field_width--)
 | 
			
		||||
                    *str++ = ' ';
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            case 'p':
 | 
			
		||||
                if (field_width == -1)
 | 
			
		||||
                {
 | 
			
		||||
                    field_width = 2 * sizeof(void *);
 | 
			
		||||
                    flags |= ZEROPAD;
 | 
			
		||||
                }
 | 
			
		||||
                str = number(str,
 | 
			
		||||
                             (unsigned long)va_arg(args, void *),
 | 
			
		||||
                             16,
 | 
			
		||||
                             field_width,
 | 
			
		||||
                             precision,
 | 
			
		||||
                             flags);
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            case 'A':
 | 
			
		||||
                flags |= UPPERCASE;
 | 
			
		||||
 | 
			
		||||
            case 'a':
 | 
			
		||||
                if (qualifier == 'l')
 | 
			
		||||
                    str = eaddr(str,
 | 
			
		||||
                                va_arg(args, unsigned char *),
 | 
			
		||||
                                field_width,
 | 
			
		||||
                                precision,
 | 
			
		||||
                                flags);
 | 
			
		||||
                else
 | 
			
		||||
                    str = iaddr(str,
 | 
			
		||||
                                va_arg(args, unsigned char *),
 | 
			
		||||
                                field_width,
 | 
			
		||||
                                precision,
 | 
			
		||||
                                flags);
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            // Integer number formats - set up the flags and "break"
 | 
			
		||||
            case 'o':
 | 
			
		||||
                base = 8;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case 'X':
 | 
			
		||||
                flags |= UPPERCASE;
 | 
			
		||||
 | 
			
		||||
            case 'x':
 | 
			
		||||
                base = 16;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case 'd':
 | 
			
		||||
            case 'i':
 | 
			
		||||
                flags |= SIGN;
 | 
			
		||||
 | 
			
		||||
            case 'u':
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
#if HAS_FLOAT
 | 
			
		||||
 | 
			
		||||
            case 'f':
 | 
			
		||||
                str = flt(str,
 | 
			
		||||
                          va_arg(args, double),
 | 
			
		||||
                          field_width,
 | 
			
		||||
                          precision,
 | 
			
		||||
                          *fmt,
 | 
			
		||||
                          flags | SIGN);
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                if (*fmt != '%')
 | 
			
		||||
                    *str++ = '%';
 | 
			
		||||
                if (*fmt)
 | 
			
		||||
                    *str++ = *fmt;
 | 
			
		||||
                else
 | 
			
		||||
                    --fmt;
 | 
			
		||||
                continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (qualifier == 'l')
 | 
			
		||||
            num = va_arg(args, unsigned long);
 | 
			
		||||
        else if (flags & SIGN)
 | 
			
		||||
            num = va_arg(args, int);
 | 
			
		||||
        else
 | 
			
		||||
            num = va_arg(args, unsigned int);
 | 
			
		||||
 | 
			
		||||
        str = number(str, num, base, field_width, precision, flags);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *str = '\0';
 | 
			
		||||
    return str - buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define UART0_BASE_ADDR 0xffff0000ULL
 | 
			
		||||
 | 
			
		||||
#define UART_REG_TXFIFO         0x00
 | 
			
		||||
#define UART_REG_RXFIFO         0x04
 | 
			
		||||
#define UART_REG_TXCTRL         0x08
 | 
			
		||||
#define UART_REG_RXCTRL         0x0c
 | 
			
		||||
#define UART_REG_IE             0x10
 | 
			
		||||
#define UART_REG_IP             0x14
 | 
			
		||||
#define UART_REG_DIV            0x18
 | 
			
		||||
#define UART_TXEN               0x1
 | 
			
		||||
 | 
			
		||||
#define UART0_REG(ADDR) *((ee_u32*) (UART0_BASE_ADDR + ADDR))
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
uart_send_char(char c)
 | 
			
		||||
{
 | 
			
		||||
      while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ;
 | 
			
		||||
      UART0_REG(UART_REG_TXFIFO) = (unsigned char)c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
ee_printf(const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
    char    buf[1024], *p;
 | 
			
		||||
    va_list args;
 | 
			
		||||
    int     n = 0;
 | 
			
		||||
 | 
			
		||||
    va_start(args, fmt);
 | 
			
		||||
    ee_vsprintf(buf, fmt, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
    p = buf;
 | 
			
		||||
    while (*p)
 | 
			
		||||
    {
 | 
			
		||||
        uart_send_char(*p);
 | 
			
		||||
        n++;
 | 
			
		||||
        p++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return n;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										241
									
								
								benchmarks/coremark/tgc/tgc.lds
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								benchmarks/coremark/tgc/tgc.lds
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,241 @@
 | 
			
		||||
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
 | 
			
		||||
OUTPUT_ARCH(riscv)
 | 
			
		||||
MEMORY
 | 
			
		||||
{
 | 
			
		||||
   RAM (rwx)  : ORIGIN = 0x0, LENGTH = 128M 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ENTRY(_start)
 | 
			
		||||
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
  /* Read-only sections, merged into text segment: */
 | 
			
		||||
  .interp         : { *(.interp) }
 | 
			
		||||
  .note.gnu.build-id  : { *(.note.gnu.build-id) }
 | 
			
		||||
  .hash           : { *(.hash) }
 | 
			
		||||
  .gnu.hash       : { *(.gnu.hash) }
 | 
			
		||||
  .dynsym         : { *(.dynsym) }
 | 
			
		||||
  .dynstr         : { *(.dynstr) }
 | 
			
		||||
  .gnu.version    : { *(.gnu.version) }
 | 
			
		||||
  .gnu.version_d  : { *(.gnu.version_d) }
 | 
			
		||||
  .gnu.version_r  : { *(.gnu.version_r) }
 | 
			
		||||
  .rela.dyn       :
 | 
			
		||||
    {
 | 
			
		||||
      *(.rela.init)
 | 
			
		||||
      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
 | 
			
		||||
      *(.rela.fini)
 | 
			
		||||
      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
 | 
			
		||||
      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
 | 
			
		||||
      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
 | 
			
		||||
      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
 | 
			
		||||
      *(.rela.ctors)
 | 
			
		||||
      *(.rela.dtors)
 | 
			
		||||
      *(.rela.got)
 | 
			
		||||
      *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
 | 
			
		||||
      *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
 | 
			
		||||
      *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
 | 
			
		||||
      *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
 | 
			
		||||
      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
 | 
			
		||||
      PROVIDE_HIDDEN (__rela_iplt_start = .);
 | 
			
		||||
      *(.rela.iplt)
 | 
			
		||||
      PROVIDE_HIDDEN (__rela_iplt_end = .);
 | 
			
		||||
    }
 | 
			
		||||
  .rela.plt       :
 | 
			
		||||
    {
 | 
			
		||||
      *(.rela.plt)
 | 
			
		||||
    }
 | 
			
		||||
  .plt            : { *(.plt) }
 | 
			
		||||
  .iplt           : { *(.iplt) }
 | 
			
		||||
  .init           :
 | 
			
		||||
  {
 | 
			
		||||
    KEEP (*(SORT_NONE(.init)))
 | 
			
		||||
    *crt0.o(.text .text.*)
 | 
			
		||||
  } > RAM
 | 
			
		||||
  .text      :
 | 
			
		||||
  {
 | 
			
		||||
    *(.text.init)
 | 
			
		||||
    *(.text.unlikely .text.*_unlikely .text.unlikely.*)
 | 
			
		||||
    *(.text.exit .text.exit.*)
 | 
			
		||||
    *(.text.startup .text.startup.*)
 | 
			
		||||
    *(.text.hot .text.hot.*)
 | 
			
		||||
    *(.text .stub .text.* .gnu.linkonce.t.*)
 | 
			
		||||
    /* .gnu.warning sections are handled specially by elf32.em.  */
 | 
			
		||||
    *(.gnu.warning)
 | 
			
		||||
  }
 | 
			
		||||
  .fini           :
 | 
			
		||||
  {
 | 
			
		||||
    KEEP (*(SORT_NONE(.fini)))
 | 
			
		||||
  }
 | 
			
		||||
  PROVIDE (__etext = .);
 | 
			
		||||
  PROVIDE (_etext = .);
 | 
			
		||||
  PROVIDE (etext = .);
 | 
			
		||||
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
 | 
			
		||||
  .rodata1        : { *(.rodata1) }
 | 
			
		||||
  .sdata2         :
 | 
			
		||||
  {
 | 
			
		||||
    *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
 | 
			
		||||
  }
 | 
			
		||||
  .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
 | 
			
		||||
  .eh_frame_hdr   : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
 | 
			
		||||
  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
 | 
			
		||||
  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
 | 
			
		||||
  .gnu_extab   : ONLY_IF_RO { *(.gnu_extab*) }
 | 
			
		||||
  /* These sections are generated by the Sun/Oracle C++ compiler.  */
 | 
			
		||||
  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges*) }
 | 
			
		||||
  /* Adjust the address for the data segment.  We want to adjust up to
 | 
			
		||||
     the same address within the page on the next page up.  */
 | 
			
		||||
  . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
 | 
			
		||||
  /* Exception handling  */
 | 
			
		||||
  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
 | 
			
		||||
  .gnu_extab      : ONLY_IF_RW { *(.gnu_extab) }
 | 
			
		||||
  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
 | 
			
		||||
  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges*) }
 | 
			
		||||
  /* Thread Local Storage sections  */
 | 
			
		||||
  .tdata	  :
 | 
			
		||||
   {
 | 
			
		||||
     PROVIDE_HIDDEN (__tdata_start = .);
 | 
			
		||||
     *(.tdata .tdata.* .gnu.linkonce.td.*)
 | 
			
		||||
   }
 | 
			
		||||
  .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
 | 
			
		||||
  .preinit_array    :
 | 
			
		||||
  {
 | 
			
		||||
    PROVIDE_HIDDEN (__preinit_array_start = .);
 | 
			
		||||
    KEEP (*(.preinit_array))
 | 
			
		||||
    PROVIDE_HIDDEN (__preinit_array_end = .);
 | 
			
		||||
  }
 | 
			
		||||
  .init_array    :
 | 
			
		||||
  {
 | 
			
		||||
    PROVIDE_HIDDEN (__init_array_start = .);
 | 
			
		||||
    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
 | 
			
		||||
    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
 | 
			
		||||
    PROVIDE_HIDDEN (__init_array_end = .);
 | 
			
		||||
  }
 | 
			
		||||
  .fini_array    :
 | 
			
		||||
  {
 | 
			
		||||
    PROVIDE_HIDDEN (__fini_array_start = .);
 | 
			
		||||
    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
 | 
			
		||||
    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
 | 
			
		||||
    PROVIDE_HIDDEN (__fini_array_end = .);
 | 
			
		||||
  }
 | 
			
		||||
  .ctors          :
 | 
			
		||||
  {
 | 
			
		||||
    /* gcc uses crtbegin.o to find the start of
 | 
			
		||||
       the constructors, so we make sure it is
 | 
			
		||||
       first.  Because this is a wildcard, it
 | 
			
		||||
       doesn't matter if the user does not
 | 
			
		||||
       actually link against crtbegin.o; the
 | 
			
		||||
       linker won't look for a file to match a
 | 
			
		||||
       wildcard.  The wildcard also means that it
 | 
			
		||||
       doesn't matter which directory crtbegin.o
 | 
			
		||||
       is in.  */
 | 
			
		||||
    KEEP (*crtbegin.o(.ctors))
 | 
			
		||||
    KEEP (*crtbegin?.o(.ctors))
 | 
			
		||||
    /* We don't want to include the .ctor section from
 | 
			
		||||
       the crtend.o file until after the sorted ctors.
 | 
			
		||||
       The .ctor section from the crtend file contains the
 | 
			
		||||
       end of ctors marker and it must be last */
 | 
			
		||||
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
 | 
			
		||||
    KEEP (*(SORT(.ctors.*)))
 | 
			
		||||
    KEEP (*(.ctors))
 | 
			
		||||
  }
 | 
			
		||||
  .dtors          :
 | 
			
		||||
  {
 | 
			
		||||
    KEEP (*crtbegin.o(.dtors))
 | 
			
		||||
    KEEP (*crtbegin?.o(.dtors))
 | 
			
		||||
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
 | 
			
		||||
    KEEP (*(SORT(.dtors.*)))
 | 
			
		||||
    KEEP (*(.dtors))
 | 
			
		||||
  }
 | 
			
		||||
  .jcr            : { KEEP (*(.jcr)) }
 | 
			
		||||
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
 | 
			
		||||
  .dynamic        : { *(.dynamic) }
 | 
			
		||||
  . = DATA_SEGMENT_RELRO_END (0, .);
 | 
			
		||||
  .data           :
 | 
			
		||||
  {
 | 
			
		||||
    __DATA_BEGIN__ = .;
 | 
			
		||||
    *(.data .data.* .gnu.linkonce.d.*)
 | 
			
		||||
    SORT(CONSTRUCTORS)
 | 
			
		||||
  }
 | 
			
		||||
  .data1          : { *(.data1) }
 | 
			
		||||
  .got            : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
 | 
			
		||||
  /* We want the small data sections together, so single-instruction offsets
 | 
			
		||||
     can access them all, and initialized data all before uninitialized, so
 | 
			
		||||
     we can shorten the on-disk segment size.  */
 | 
			
		||||
  .sdata          :
 | 
			
		||||
  {
 | 
			
		||||
    __SDATA_BEGIN__ = .;
 | 
			
		||||
    *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
 | 
			
		||||
    *(.sdata .sdata.* .gnu.linkonce.s.*)
 | 
			
		||||
  }
 | 
			
		||||
  _edata = .; PROVIDE (edata = .);
 | 
			
		||||
  . = .;
 | 
			
		||||
  __bss_start = .;
 | 
			
		||||
  .sbss           :
 | 
			
		||||
  {
 | 
			
		||||
    *(.dynsbss)
 | 
			
		||||
    *(.sbss .sbss.* .gnu.linkonce.sb.*)
 | 
			
		||||
    *(.scommon)
 | 
			
		||||
  }
 | 
			
		||||
  .bss            :
 | 
			
		||||
  {
 | 
			
		||||
   *(.dynbss)
 | 
			
		||||
   *(.bss .bss.* .gnu.linkonce.b.*)
 | 
			
		||||
   *(COMMON)
 | 
			
		||||
   /* Align here to ensure that the .bss section occupies space up to
 | 
			
		||||
      _end.  Align after .bss to ensure correct alignment even if the
 | 
			
		||||
      .bss section disappears because there are no input sections.
 | 
			
		||||
      FIXME: Why do we need it? When there is no .bss section, we do not
 | 
			
		||||
      pad the .data section.  */
 | 
			
		||||
   . = ALIGN(. != 0 ? 32 / 8 : 1);
 | 
			
		||||
  }
 | 
			
		||||
  . = ALIGN(32 / 8);
 | 
			
		||||
  . = SEGMENT_START("ldata-segment", .);
 | 
			
		||||
  . = ALIGN(32 / 8);
 | 
			
		||||
  __BSS_END__ = .;
 | 
			
		||||
    __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,
 | 
			
		||||
		            MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
 | 
			
		||||
  _end = .; PROVIDE (end = .);
 | 
			
		||||
  . = DATA_SEGMENT_END (.);
 | 
			
		||||
  /* Stabs debugging sections.  */
 | 
			
		||||
  .stab          0 : { *(.stab) }
 | 
			
		||||
  .stabstr       0 : { *(.stabstr) }
 | 
			
		||||
  .stab.excl     0 : { *(.stab.excl) }
 | 
			
		||||
  .stab.exclstr  0 : { *(.stab.exclstr) }
 | 
			
		||||
  .stab.index    0 : { *(.stab.index) }
 | 
			
		||||
  .stab.indexstr 0 : { *(.stab.indexstr) }
 | 
			
		||||
  .comment       0 : { *(.comment) }
 | 
			
		||||
  .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
 | 
			
		||||
  /* DWARF debug sections.
 | 
			
		||||
     Symbols in the DWARF debugging sections are relative to the beginning
 | 
			
		||||
     of the section so we begin them at 0.  */
 | 
			
		||||
  /* DWARF 1 */
 | 
			
		||||
  .debug          0 : { *(.debug) }
 | 
			
		||||
  .line           0 : { *(.line) }
 | 
			
		||||
  /* GNU DWARF 1 extensions */
 | 
			
		||||
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
 | 
			
		||||
  .debug_sfnames  0 : { *(.debug_sfnames) }
 | 
			
		||||
  /* DWARF 1.1 and DWARF 2 */
 | 
			
		||||
  .debug_aranges  0 : { *(.debug_aranges) }
 | 
			
		||||
  .debug_pubnames 0 : { *(.debug_pubnames) }
 | 
			
		||||
  /* DWARF 2 */
 | 
			
		||||
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
 | 
			
		||||
  .debug_abbrev   0 : { *(.debug_abbrev) }
 | 
			
		||||
  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end) }
 | 
			
		||||
  .debug_frame    0 : { *(.debug_frame) }
 | 
			
		||||
  .debug_str      0 : { *(.debug_str) }
 | 
			
		||||
  .debug_loc      0 : { *(.debug_loc) }
 | 
			
		||||
  .debug_macinfo  0 : { *(.debug_macinfo) }
 | 
			
		||||
  /* SGI/MIPS DWARF 2 extensions */
 | 
			
		||||
  .debug_weaknames 0 : { *(.debug_weaknames) }
 | 
			
		||||
  .debug_funcnames 0 : { *(.debug_funcnames) }
 | 
			
		||||
  .debug_typenames 0 : { *(.debug_typenames) }
 | 
			
		||||
  .debug_varnames  0 : { *(.debug_varnames) }
 | 
			
		||||
  /* DWARF 3 */
 | 
			
		||||
  .debug_pubtypes 0 : { *(.debug_pubtypes) }
 | 
			
		||||
  .debug_ranges   0 : { *(.debug_ranges) }
 | 
			
		||||
  /* DWARF Extension.  */
 | 
			
		||||
  .debug_macro    0 : { *(.debug_macro) }
 | 
			
		||||
  .debug_addr     0 : { *(.debug_addr) }
 | 
			
		||||
  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
 | 
			
		||||
  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user