Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libgloss/frv/crt0.S')
-rw-r--r--libgloss/frv/crt0.S231
1 files changed, 231 insertions, 0 deletions
diff --git a/libgloss/frv/crt0.S b/libgloss/frv/crt0.S
new file mode 100644
index 000000000..0825a5efc
--- /dev/null
+++ b/libgloss/frv/crt0.S
@@ -0,0 +1,231 @@
+/* crt0.S -- startup file for frv.
+ *
+ * Copyright (c) 2002 Red Hat, Inc
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <frv-asm.h>
+
+ /* statically store .Lcall's address so we can see if we are running
+ at the location we were linked for or a different location. */
+ .data
+ .type EXT(__start_cmp),@object
+ .size EXT(__start_cmp),4
+ .p2align 2
+EXT(__start_cmp):
+ .picptr .Lcall
+
+ .globl __start
+ .weak _start
+ .text
+ .type __start,@function
+__start:
+_start:
+ call .Lcall /* set up _gp in a pic-friendly manor */
+.Lcall: movsg lr, gr4
+ P(sethi) #gprelhi(.Lcall), gr5
+ setlo #gprello(.Lcall), gr5
+ P(sub) gr4, gr5, gr16
+
+ sethi #gprelhi(EXT(_stack)), sp /* load up stack pointer */
+ P(setlo) #gprello(EXT(_stack)), sp
+ setlos #0, fp /* zero fp to allow unwinders to stop */
+ P(add) sp, gr16, sp
+
+ sethi #gprelhi(EXT(__start_cmp)), gr5
+ setlo #gprello(EXT(__start_cmp)), gr5
+ ld @(gr5,gr16), gr6
+ subcc gr4, gr6, gr8, icc0
+ beq icc0, 0, .Lfixed
+
+ P(st) gr4, @(gr5, gr16) /* update so if we restart no need to fixup */
+
+ /* fixup the .ctors list */
+ sethi #gprelhi(EXT(__CTOR_LIST__)), gr9
+ P(sethi) #gprelhi(EXT(__CTOR_END__)), gr10
+ setlo #gprello(EXT(__CTOR_LIST__)), gr9
+ P(setlo) #gprello(EXT(__CTOR_END__)), gr10
+ add gr9, gr16, gr9
+ P(add) gr10, gr16, gr10
+ addi gr9, 4, gr9
+ P(subi) gr10, 4, gr10
+ setlos 4, gr11
+ call EXT(__frv_fixptrs)
+
+ /* fixup the .dtors list */
+ P(sethi) #gprelhi(EXT(__DTOR_LIST__)), gr9
+ sethi #gprelhi(EXT(__DTOR_END__)), gr10
+ P(setlo) #gprello(EXT(__DTOR_LIST__)), gr9
+ setlo #gprello(EXT(__DTOR_END__)), gr10
+ P(add) gr9, gr16, gr9
+ add gr10, gr16, gr10
+ P(addi) gr9, 4, gr9
+ subi gr10, 4, gr10
+ call EXT(__frv_fixptrs)
+
+ /* fixup the .dtors list */
+ P(sethi) #gprelhi(EXT(__ROFIXUP_LIST__)), gr9
+ sethi #gprelhi(EXT(__ROFIXUP_END__)), gr10
+ P(setlo) #gprello(EXT(__ROFIXUP_LIST__)), gr9
+ setlo #gprello(EXT(__ROFIXUP_END__)), gr10
+ P(add) gr9, gr16, gr9
+ add gr10, gr16, gr10
+ call EXT(__frv_fix_usrptrs)
+
+.Lfixed:
+
+/* HSR flags */
+#define HSR_ICE 0x80000000 /* Instruction cache enable */
+#define HSR_DCE 0x40000000 /* Data cache enable */
+#define HSR_CBM 0x08000000 /* Cache copy back mode */
+#define HSR_EIMM 0x04000000 /* Enable Instruction MMU */
+#define HSR_EDMM 0x02000000 /* Enable Data MMU */
+#define HSR_EMEM 0x00800000 /* Enable MMU miss exception mask */
+#define HSR_RME 0x00400000 /* Ram mode enable */
+#define HSR_SA 0x00001000 /* Start address */
+#define HSR_FRN 0x00000800 /* Number of FPRs */
+#define HSR_GRN 0x00000400 /* Number of GPRs */
+#define HSR_FRHE 0x00000200 /* FR Higher Enable */
+#define HSR_FRLE 0x00000100 /* FR Lower Enable */
+#define HSR_GRHE 0x00000080 /* GR Higher Enable */
+#define HSR_GRLE 0x00000040 /* GR Lower Enable */
+
+#ifndef HSR_CLEAR
+#define HSR_CLEAR 0
+#endif
+
+#ifndef HSR_SET
+#ifndef FRV_NO_CACHE
+#define HSR_SET (HSR_ICE|HSR_DCE|HSR_FRHE|HSR_FRLE|HSR_GRHE|HSR_GRLE)
+#else
+#define HSR_SET (HSR_FRHE|HSR_FRLE|HSR_GRHE|HSR_GRLE)
+#endif
+#endif
+
+/* PSR flags */
+#define PSR_ICE 0x00010000 /* In circuit emulation mode */
+#define PSR_NEM 0x00004000 /* Non-exception mode */
+#define PSR_CM 0x00002000 /* Conditional mode */
+#define PSR_BE 0x00001000 /* Big endian mode */
+#define PSR_EF 0x00000100 /* Enable floating point */
+#define PSR_EM 0x00000080 /* Enable media instructions */
+#define PSR_S 0x00000004 /* Enable supervisor mode */
+#define PSR_PS 0x00000002 /* Previous supervisor mode */
+#define PSR_ET 0x00000001 /* Enable interrupts */
+
+#ifndef PSR_CLEAR
+#if __FRV_FPR__
+#define PSR_CLEAR 0
+#else
+#define PSR_CLEAR (PSR_EF|PSR_EM)
+#endif
+#endif
+
+#ifndef PSR_SET
+#if __FRV_FPR__
+#define PSR_SET (PSR_NEM|PSR_CM|PSR_EF|PSR_EM)
+#else
+#define PSR_SET (PSR_NEM|PSR_CM)
+#endif
+#endif
+
+ /* Enable floating point */
+ movsg hsr0, gr4
+ P(sethi) #hi(HSR_SET), gr5
+ setlo #lo(HSR_SET), gr5
+ P(sethi) #hi(~HSR_CLEAR), gr6
+ setlo #lo(~HSR_CLEAR), gr6
+ or gr4, gr5, gr4
+ and gr4, gr6, gr4
+ movgs gr4, hsr0
+
+ movsg psr, gr4
+ P(sethi) #hi(PSR_SET), gr5
+ setlo #lo(PSR_SET), gr5
+ P(sethi) #hi(~PSR_CLEAR), gr6
+ setlo #lo(~PSR_CLEAR), gr6
+ or gr4, gr5, gr4
+ and gr4, gr6, gr4
+ movgs gr4, psr
+
+ /* zero the bss area */
+ P(sethi) #gprelhi(__bss_start), gr8
+ sethi #gprelhi(__end), gr4
+ P(setlo) #gprello(__bss_start), gr8
+ setlo #gprello(__end), gr4
+ P(add) gr8, gr16, gr8
+ add gr4, gr16, gr4
+ P(setlos) #0, gr9
+ sub gr4, gr8, gr10
+ call EXT(memset)
+
+ P(setlos) #0, gr8 /* zero argc, argv, envp */
+ setlos #0, gr9
+ P(setlos) #0, gr10
+
+ call EXT(main)
+ call EXT(exit)
+.Lend:
+ .size __start,(.Lend-__start)
+
+ /* Routine to adjust pointers
+ gr8 = difference to adjust by
+ gr9 = starting address
+ gr10 = ending address + 4
+ gr11 = amount to add to the pointer each iteration. */
+ .globl EXT(__frv_fixptrs)
+ .type EXT(__frv_fixptrs),@function
+EXT(__frv_fixptrs):
+ P(sub) gr9, gr11, gr9
+ sub gr10, gr11, gr10
+.Lloop2:
+ cmp gr10, gr9, icc0
+ bls icc0, 0, .Lret2
+
+ ldu @(gr9,gr11), gr5
+ add gr8, gr5, gr5
+ P(st) gr5, @(gr9,gr0)
+ bra .Lloop2
+
+.Lret2: ret
+.Lend2:
+ .size EXT(__frv_fixptrs),.Lend2-EXT(__frv_fixptrs)
+
+ /* Routine to adjust statically initialized pointers
+ Note since these are pointers to pointers, they
+ need to be adjusted themsevles.
+
+ gr8 = difference to adjust by
+ gr9 = starting address
+ gr10 = ending address + 4
+ gr11 = amount to add to the pointer each iteration. */
+ .globl EXT(__frv_fix_usrptrs)
+ .type EXT(__frv_fix_usrptrs),@function
+EXT(__frv_fix_usrptrs):
+ P(sub) gr9, gr11, gr9
+ sub gr10, gr11, gr10
+.Lloop3:
+ cmp gr10, gr9, icc0
+ bls icc0, 0, .Lret3
+
+ ldu @(gr9,gr11), gr5
+ ld @(gr5, gr8), gr6
+ cmp gr6, gr0, icc0 /* skip pointers initialized to 0 */
+ beq icc0, 0, .Lloop3
+
+ add gr8, gr6, gr6
+ P(st) gr6, @(gr5,gr8)
+ bra .Lloop3
+
+.Lret3: ret
+.Lend3:
+ .size EXT(__frv_fix_usrptrs),.Lend2-EXT(__frv_fix_usrptrs)