Merge in VideoCore IV code generator.
--HG-- branch : default-branch
This commit is contained in:
		
						commit
						436db46f48
					
				
					 85 changed files with 4750 additions and 22 deletions
				
			
		
							
								
								
									
										3
									
								
								.distr
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								.distr
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -48,6 +48,7 @@ mach/i80
 | 
			
		|||
mach/i86
 | 
			
		||||
mach/i386
 | 
			
		||||
mach/m68020
 | 
			
		||||
mach/vc4
 | 
			
		||||
 | 
			
		||||
plat
 | 
			
		||||
plat/cpm
 | 
			
		||||
| 
						 | 
				
			
			@ -55,5 +56,7 @@ plat/pc86
 | 
			
		|||
plat/linux
 | 
			
		||||
plat/linux386
 | 
			
		||||
plat/linux68k
 | 
			
		||||
plat/rpi
 | 
			
		||||
 | 
			
		||||
examples
 | 
			
		||||
man
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -54,6 +54,8 @@ CFLAGS += \
 | 
			
		|||
 | 
			
		||||
LDFLAGS +=
 | 
			
		||||
 | 
			
		||||
ACKFLAGS = -Ih
 | 
			
		||||
 | 
			
		||||
all: installables
 | 
			
		||||
 | 
			
		||||
.DELETE_ON_ERROR:
 | 
			
		||||
| 
						 | 
				
			
			@ -101,6 +103,7 @@ include mach/i386/build.mk
 | 
			
		|||
include mach/i86/build.mk
 | 
			
		||||
include mach/m68020/build.mk
 | 
			
		||||
# include mach/powerpc/build.mk
 | 
			
		||||
include mach/vc4/build.mk
 | 
			
		||||
 | 
			
		||||
include plat/build.mk
 | 
			
		||||
include plat/pc86/build.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +111,7 @@ include plat/cpm/build.mk
 | 
			
		|||
include plat/linux386/build.mk
 | 
			
		||||
include plat/linux68k/build.mk
 | 
			
		||||
# include plat/linuxppc/build.mk
 | 
			
		||||
include plat/rpi/build.mk
 | 
			
		||||
 | 
			
		||||
.PHONY: installables
 | 
			
		||||
installables: $(INSTALLABLES)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								README
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								README
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -32,6 +32,7 @@ pc86          produces bootable floppy disk images for 8086 PCs
 | 
			
		|||
linux386      produces ELF executables for PC Linux systems
 | 
			
		||||
linux68k      produces ELF executables for m68020 Linux systems
 | 
			
		||||
cpm           produces i80 CP/M .COM files
 | 
			
		||||
rpi           produces Raspberry Pi GPU binaries
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
INSTALLATION
 | 
			
		||||
| 
						 | 
				
			
			@ -128,7 +129,7 @@ GOTCHAS
 | 
			
		|||
 | 
			
		||||
There are some things you should be aware of.
 | 
			
		||||
 | 
			
		||||
- Look at plat/<PLATFORMNAME>/README for information about the two supported
 | 
			
		||||
- Look at plat/<PLATFORMNAME>/README for information about the supported
 | 
			
		||||
  platforms.
 | 
			
		||||
  
 | 
			
		||||
- The library support is fairly limited; for C, it's at roughly the ANSI C
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ define reset
 | 
			
		|||
	$(eval o :=)
 | 
			
		||||
	$(eval s :=)
 | 
			
		||||
	$(eval cflags :=)
 | 
			
		||||
	$(eval ackflags :=)
 | 
			
		||||
	$(eval ldflags :=)
 | 
			
		||||
	$(eval objdir :=)
 | 
			
		||||
endef
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								h/out.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								h/out.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -64,6 +64,7 @@ struct outname {
 | 
			
		|||
#define RELO4	   3			/* 4 bytes */
 | 
			
		||||
#define RELOPPC    4            /* PowerPC 26-bit address */
 | 
			
		||||
#define RELOH2     5            /* write top 2 bytes of 4 byte word */
 | 
			
		||||
#define RELOVC4    6            /* VideoCore IV address in 32-bit instruction */
 | 
			
		||||
 | 
			
		||||
#define RELPC	0x08			/* pc relative */
 | 
			
		||||
#define RELBR	0x10			/* High order byte lowest address. */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@ define build-libcc-ansi-headers-impl
 | 
			
		|||
		float.h \
 | 
			
		||||
		limits.h \
 | 
			
		||||
		math.h \
 | 
			
		||||
		malloc.h \
 | 
			
		||||
		setjmp.h \
 | 
			
		||||
		signal.h \
 | 
			
		||||
		stdarg.h \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,3 +20,4 @@ stdbool.h
 | 
			
		|||
fcntl.h
 | 
			
		||||
tgmath.h
 | 
			
		||||
locale.h
 | 
			
		||||
malloc.h
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										66
									
								
								lang/cem/libcc.ansi/headers/malloc.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								lang/cem/libcc.ansi/headers/malloc.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
/*
 | 
			
		||||
 * stdlib.h - standard library
 | 
			
		||||
 *
 | 
			
		||||
 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | 
			
		||||
 * See the copyright notice in the ACK home directory, in the file "Copyright".
 | 
			
		||||
 */
 | 
			
		||||
/* $Id$ */
 | 
			
		||||
 | 
			
		||||
#ifndef _STDLIB_H
 | 
			
		||||
#define	_STDLIB_H
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
#define	EXIT_FAILURE 1
 | 
			
		||||
#define	EXIT_SUCCESS 0
 | 
			
		||||
#define	RAND_MAX 32767
 | 
			
		||||
#define	MB_CUR_MAX sizeof(wchar_t)
 | 
			
		||||
 | 
			
		||||
typedef struct { int quot, rem; } div_t;
 | 
			
		||||
typedef struct { long quot, rem; } ldiv_t;
 | 
			
		||||
 | 
			
		||||
extern double atof(const char *_nptr);
 | 
			
		||||
extern int atoi(const char *_nptr);
 | 
			
		||||
extern long atol(const char *_nptr);
 | 
			
		||||
extern double strtod(const char *_nptr, char **_endptr);
 | 
			
		||||
extern long strtol(const char *_nptr, char **_endptr, int _base);
 | 
			
		||||
extern unsigned long strtoul(const char *_nptr, char **_endptr, int _base);
 | 
			
		||||
extern int rand(void);
 | 
			
		||||
extern void srand(unsigned int _seed);
 | 
			
		||||
extern void* calloc(size_t _nmemb, size_t _size);
 | 
			
		||||
extern void free(void *_ptr);
 | 
			
		||||
extern void* malloc(size_t _size);
 | 
			
		||||
extern void* realloc(void *_ptr, size_t _size);
 | 
			
		||||
extern void abort(void);
 | 
			
		||||
extern int atexit(void (*_func)(void));
 | 
			
		||||
extern void exit(int _status);
 | 
			
		||||
extern void _Exit(int _status);
 | 
			
		||||
extern char* getenv(const char *_name);
 | 
			
		||||
extern int setenv(const char *_name, const char *_value, int _overwrite);
 | 
			
		||||
extern int unsetenv(const char *_name);
 | 
			
		||||
extern int putenv(char *_string);
 | 
			
		||||
extern int system(const char *_string);
 | 
			
		||||
extern void* bsearch(const void *_key, const void *_base,
 | 
			
		||||
			size_t _nmemb, size_t _size,
 | 
			
		||||
			int (*_compar)(const void *, const void *));
 | 
			
		||||
extern void qsort(void *_base, size_t _nmemb, size_t _size,
 | 
			
		||||
			int (*_compar)(const void *, const void *));
 | 
			
		||||
extern int abs(int _j);
 | 
			
		||||
extern div_t div(int _numer, int _denom);
 | 
			
		||||
extern long labs(long _j);
 | 
			
		||||
extern ldiv_t ldiv(long _numer, long _denom);
 | 
			
		||||
extern int mblen(const char *_s, size_t _n);
 | 
			
		||||
extern int mbtowc(wchar_t *_pwc, const char *_s, size_t _n);
 | 
			
		||||
extern int wctomb(char *_s, wchar_t _wchar);
 | 
			
		||||
extern size_t mbstowcs(wchar_t *_pwcs, const char *_s, size_t _n);
 | 
			
		||||
extern size_t wcstombs(char *_s, const wchar_t *_pwcs, size_t _n);
 | 
			
		||||
 | 
			
		||||
/* Extensions (not part of the standard) */
 | 
			
		||||
 | 
			
		||||
#define atof(n)   strtod(n, (char **)NULL)
 | 
			
		||||
#define atoi(n)   ((int)strtol(n, (char **)NULL, 10))
 | 
			
		||||
#define atol(n)   strtol(n, (char **)NULL, 10)
 | 
			
		||||
#define atoll(n)  strtoll(n, (char **)NULL, 10)
 | 
			
		||||
#define mblen(s, n)   mbtowc((wchar_t *)0, s, n)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ typedef unsigned short  uint16_t;
 | 
			
		|||
 | 
			
		||||
#if	_EM_WSIZE == 4
 | 
			
		||||
typedef signed int      int32_t;
 | 
			
		||||
typedef unsigned short  uint32_t;
 | 
			
		||||
typedef unsigned int    uint32_t;
 | 
			
		||||
#else
 | 
			
		||||
typedef signed long     int32_t;
 | 
			
		||||
typedef unsigned long   uint32_t;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,7 @@ rewind.c
 | 
			
		|||
scanf.c
 | 
			
		||||
setbuf.c
 | 
			
		||||
setvbuf.c
 | 
			
		||||
snprintf.c
 | 
			
		||||
sprintf.c
 | 
			
		||||
sscanf.c
 | 
			
		||||
tmpfile.c
 | 
			
		||||
| 
						 | 
				
			
			@ -47,3 +48,4 @@ ungetc.c
 | 
			
		|||
vfprintf.c
 | 
			
		||||
vprintf.c
 | 
			
		||||
vsprintf.c
 | 
			
		||||
vsnprintf.c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ mbstowcs.c
 | 
			
		|||
mbtowc.c
 | 
			
		||||
qsort.c
 | 
			
		||||
rand.c
 | 
			
		||||
setenv.c
 | 
			
		||||
strtod.c
 | 
			
		||||
strtol.c
 | 
			
		||||
system.c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@ strcmp.c
 | 
			
		|||
strcoll.c
 | 
			
		||||
strcpy.c
 | 
			
		||||
strcspn.c
 | 
			
		||||
strdup.c
 | 
			
		||||
strerror.c
 | 
			
		||||
strlen.c
 | 
			
		||||
strncat.c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ name cem
 | 
			
		|||
		-DEM_SSIZE={s} -DEM_LSIZE={l} -DEM_FSIZE={f} -DEM_DSIZE={d}) \
 | 
			
		||||
		-D_EM_WSIZE={w} -D_EM_PSIZE={p} \
 | 
			
		||||
		-D_EM_SSIZE={s} -D_EM_LSIZE={l} -D_EM_FSIZE={f} -D_EM_DSIZE={d} \
 | 
			
		||||
		-Vw{w}.{w}i{w}.{w}p{p}.{w}f{f}.{w}s{s}.{s}l{l}.{w}d{d}.{w} \
 | 
			
		||||
		-Vw{w}.{wa}i{w}.{wa}p{p}.{pa}f{f}.{fa}s{s}.{sa}l{l}.{la}d{d}.{da}x{x}.{xa} \
 | 
			
		||||
		{CC_ALIGN?} \
 | 
			
		||||
		{CEM_F?} {LFLAG?} < >
 | 
			
		||||
	callname acc
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@ s2650
 | 
			
		|||
sun3
 | 
			
		||||
sun2
 | 
			
		||||
vax4
 | 
			
		||||
vc4
 | 
			
		||||
xenix3
 | 
			
		||||
z80
 | 
			
		||||
z8000
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,9 @@ define build-as-impl
 | 
			
		|||
 | 
			
		||||
$(eval CLEANABLES += $(OBJDIR)/$D/preprocessed-comm2.y)
 | 
			
		||||
$(OBJDIR)/$D/preprocessed-comm2.y: mach/proto/as/comm2.y $(CPPANSI) \
 | 
			
		||||
		mach/$(ARCH)/as/mach1.c \
 | 
			
		||||
		mach/$(ARCH)/as/mach2.c \
 | 
			
		||||
		mach/$(ARCH)/as/mach3.c \
 | 
			
		||||
		mach/$(ARCH)/as/mach4.c
 | 
			
		||||
	@echo PREPROCESS $$@
 | 
			
		||||
	@mkdir -p $$(dir $$@)
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +41,10 @@ $(OBJDIR)/$D/preprocessed-comm2.y: mach/proto/as/comm2.y $(CPPANSI) \
 | 
			
		|||
	$(call rawfile, $(LIBOBJECT))
 | 
			
		||||
    $(call cprogram, $(BINDIR)/$(PLATFORM)/as)
 | 
			
		||||
    $(call installto, $(PLATDEP)/$(PLATFORM)/as)
 | 
			
		||||
 | 
			
		||||
    $(call reset)
 | 
			
		||||
    $(call file, man/$(ARCH)_as.6)
 | 
			
		||||
    $(call installto, $(INSDIR)/share/man/man6/$(ARCH)_as.6)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
build-as = $(eval $(build-as-impl))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,6 +82,8 @@ extern char em_flag[];
 | 
			
		|||
extern short em_ptyp[];
 | 
			
		||||
extern double atof();
 | 
			
		||||
 | 
			
		||||
void prolog(full nlocals);
 | 
			
		||||
 | 
			
		||||
/* Own version of atol that continues computing on overflow.
 | 
			
		||||
   We don't know that about the ANSI C one.
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								mach/vc4/.distr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								mach/vc4/.distr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
build.mk
 | 
			
		||||
as
 | 
			
		||||
ncg
 | 
			
		||||
libem
 | 
			
		||||
libend
 | 
			
		||||
							
								
								
									
										7
									
								
								mach/vc4/as/.distr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								mach/vc4/as/.distr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
mach0.c
 | 
			
		||||
mach1.c
 | 
			
		||||
mach2.c
 | 
			
		||||
mach3.c
 | 
			
		||||
mach4.c
 | 
			
		||||
mach5.c
 | 
			
		||||
binary.h
 | 
			
		||||
							
								
								
									
										34
									
								
								mach/vc4/as/binary.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								mach/vc4/as/binary.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,34 @@
 | 
			
		|||
/*
 | 
			
		||||
 * VideoCore IV assembler for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BINARY_H
 | 
			
		||||
#define BINARY_H
 | 
			
		||||
 | 
			
		||||
/* This grotesque nonsense allows us to use binary constants from C. */
 | 
			
		||||
 | 
			
		||||
#define HEX__(n) 0x##n##LU
 | 
			
		||||
#define B8__(x) \
 | 
			
		||||
	((x&0x0000000FLU)?1:0) \
 | 
			
		||||
	+((x&0x000000F0LU)?2:0) \
 | 
			
		||||
	+((x&0x00000F00LU)?4:0) \
 | 
			
		||||
	+((x&0x0000F000LU)?8:0) \
 | 
			
		||||
	+((x&0x000F0000LU)?16:0) \
 | 
			
		||||
	+((x&0x00F00000LU)?32:0) \
 | 
			
		||||
	+((x&0x0F000000LU)?64:0) \
 | 
			
		||||
	+((x&0xF0000000LU)?128:0)
 | 
			
		||||
 | 
			
		||||
#define B8(d) \
 | 
			
		||||
	((unsigned char)B8__(HEX__(d)))
 | 
			
		||||
#define B16(dmsb,dlsb) \
 | 
			
		||||
	(((unsigned short)B8(dmsb)<<8) + B8(dlsb))
 | 
			
		||||
#define B32(dmsb,db2,db3,dlsb) \
 | 
			
		||||
	  (((unsigned long)B8(dmsb)<<24) \
 | 
			
		||||
	+ ((unsigned long)B8(db2)<<16) \
 | 
			
		||||
	+ ((unsigned long)B8(db3)<<8) \
 | 
			
		||||
	+ B8(dlsb))
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										32
									
								
								mach/vc4/as/mach0.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								mach/vc4/as/mach0.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
/*
 | 
			
		||||
 * VideoCore IV assembler for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define	THREE_PASS          /* branch and offset optimization */
 | 
			
		||||
#define LISTING             /* enable listing facilities */
 | 
			
		||||
#define RELOCATION          /* generate relocatable code */
 | 
			
		||||
#define DEBUG 0
 | 
			
		||||
 | 
			
		||||
#undef valu_t
 | 
			
		||||
#define valu_t long
 | 
			
		||||
 | 
			
		||||
#undef ADDR_T
 | 
			
		||||
#define ADDR_T long
 | 
			
		||||
 | 
			
		||||
#undef word_t
 | 
			
		||||
#define word_t long
 | 
			
		||||
 | 
			
		||||
typedef unsigned long quad;
 | 
			
		||||
 | 
			
		||||
#undef ALIGNWORD
 | 
			
		||||
#define ALIGNWORD	4
 | 
			
		||||
 | 
			
		||||
#undef ALIGNSECT
 | 
			
		||||
#define ALIGNSECT	4
 | 
			
		||||
 | 
			
		||||
#undef VALWIDTH
 | 
			
		||||
#define VALWIDTH	8
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28
									
								
								mach/vc4/as/mach1.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								mach/vc4/as/mach1.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
/*
 | 
			
		||||
 * VideoCore IV assembler for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "binary.h"
 | 
			
		||||
 | 
			
		||||
#define ALWAYS 14
 | 
			
		||||
 | 
			
		||||
extern void alu_instr_reg(quad opcode, int cc, int rd, int ra, int rb);
 | 
			
		||||
extern void alu_instr_lit(quad opcode, int cc, int rd, int ra, long value);
 | 
			
		||||
extern void misc_instr_reg(quad opcode, int cc, int rd, int ra, int rb);
 | 
			
		||||
extern void misc_instr_lit(quad opcode, int cc, int rd, int ra, quad value);
 | 
			
		||||
extern void branch_instr(int bl, int cc, struct expr_t* expr);
 | 
			
		||||
extern void stack_instr(quad opcode, int loreg, int hireg, int extrareg);
 | 
			
		||||
extern void mem_instr(quad opcode, int cc, int rd, long offset, int rs);
 | 
			
		||||
extern void mem_offset_instr(quad opcode, int cc, int rd, int qa, int rb);
 | 
			
		||||
extern void mem_postincr_instr(quad opcode, int cc, int rd, int rs);
 | 
			
		||||
extern void mem_address_instr(quad opcode, int rd, struct expr_t* expr);
 | 
			
		||||
extern void branch_addcmp_reg_reg_instr(int cc, int rd, int ra, int rs, struct expr_t* expr);
 | 
			
		||||
extern void branch_addcmp_lit_reg_instr(int cc, int rd, long va, int rs, struct expr_t* expr);
 | 
			
		||||
extern void branch_addcmp_reg_lit_instr(int cc, int rd, int ra, long vs, struct expr_t* expr);
 | 
			
		||||
extern void branch_addcmp_lit_lit_instr(int cc, int rd, long va, long vs, struct expr_t* expr);
 | 
			
		||||
extern void lea_stack_instr(int rd, long va, int rs);
 | 
			
		||||
extern void lea_address_instr(int rd, struct expr_t* expr);
 | 
			
		||||
extern void fltcnv_instr(quad opcode, int cc, int rd, int ra, quad shift);
 | 
			
		||||
							
								
								
									
										24
									
								
								mach/vc4/as/mach2.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								mach/vc4/as/mach2.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
/*
 | 
			
		||||
 * VideoCore IV assembler for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
%token <y_word> GPR
 | 
			
		||||
%token <y_word> CC
 | 
			
		||||
 | 
			
		||||
%token <y_word> OP
 | 
			
		||||
%token <y_word> OP_BRANCH OP_BRANCHLINK OP_ADDCMPB
 | 
			
		||||
%token <y_word> OP_ONEREG
 | 
			
		||||
%token <y_word> OP_ONELREG
 | 
			
		||||
%token <y_word> OP_ALU
 | 
			
		||||
%token <y_word> OP_FPU
 | 
			
		||||
%token <y_word> OP_MEM
 | 
			
		||||
%token <y_word> OP_MISC
 | 
			
		||||
%token <y_word> OP_MISCL
 | 
			
		||||
%token <y_word> OP_FLTCNV
 | 
			
		||||
%token <y_word> OP_STACK
 | 
			
		||||
%token <y_word> OP_LEA
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										153
									
								
								mach/vc4/as/mach3.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								mach/vc4/as/mach3.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,153 @@
 | 
			
		|||
/*
 | 
			
		||||
 * VideoCore IV assembler for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Integer registers */
 | 
			
		||||
 | 
			
		||||
0,     GPR,        0,          "r0",
 | 
			
		||||
0,     GPR,        1,          "r1",
 | 
			
		||||
0,     GPR,        2,          "r2",
 | 
			
		||||
0,     GPR,        3,          "r3",
 | 
			
		||||
0,     GPR,        4,          "r4",
 | 
			
		||||
0,     GPR,        5,          "r5",
 | 
			
		||||
 | 
			
		||||
0,     GPR,        6,          "r6",
 | 
			
		||||
0,     GPR,        7,          "r7",
 | 
			
		||||
0,     GPR,        8,          "r8",
 | 
			
		||||
0,     GPR,        9,          "r9",
 | 
			
		||||
0,     GPR,        10,         "r10",
 | 
			
		||||
0,     GPR,        11,         "r11",
 | 
			
		||||
0,     GPR,        12,         "r12",
 | 
			
		||||
0,     GPR,        13,         "r13",
 | 
			
		||||
0,     GPR,        14,         "r14",
 | 
			
		||||
0,     GPR,        15,         "r15",
 | 
			
		||||
0,     GPR,        16,         "r16",
 | 
			
		||||
0,     GPR,        17,         "r17",
 | 
			
		||||
0,     GPR,        18,         "r18",
 | 
			
		||||
0,     GPR,        19,         "r19",
 | 
			
		||||
0,     GPR,        20,         "r20",
 | 
			
		||||
0,     GPR,        21,         "r21",
 | 
			
		||||
0,     GPR,        22,         "r22",
 | 
			
		||||
0,     GPR,        23,         "r23",
 | 
			
		||||
0,     GPR,        24,         "r24",
 | 
			
		||||
0,     GPR,        24,         "fp",
 | 
			
		||||
 | 
			
		||||
0,     GPR,        25,         "r25",
 | 
			
		||||
0,     GPR,        25,         "sp",
 | 
			
		||||
0,     GPR,        26,         "r26",
 | 
			
		||||
0,     GPR,        26,         "lr",
 | 
			
		||||
0,     GPR,        27,         "r27",
 | 
			
		||||
0,     GPR,        28,         "r28",
 | 
			
		||||
0,     GPR,        29,         "r29",
 | 
			
		||||
0,     GPR,        30,         "r30",
 | 
			
		||||
0,     GPR,        30,         "sr",
 | 
			
		||||
0,     GPR,        31,         "r31",
 | 
			
		||||
0,     GPR,        31,         "pc",
 | 
			
		||||
 | 
			
		||||
/* Condition codes */
 | 
			
		||||
 | 
			
		||||
0,     CC,         0,          ".eq",
 | 
			
		||||
0,     CC,         1,          ".ne",
 | 
			
		||||
0,     CC,         2,          ".cs",
 | 
			
		||||
0,     CC,         2,          ".lo",
 | 
			
		||||
0,     CC,         3,          ".cc",
 | 
			
		||||
0,     CC,         3,          ".hs",
 | 
			
		||||
0,     CC,         4,          ".mi",
 | 
			
		||||
0,     CC,         5,          ".pl",
 | 
			
		||||
0,     CC,         6,          ".vs",
 | 
			
		||||
0,     CC,         7,          ".vc",
 | 
			
		||||
0,     CC,         8,          ".hi",
 | 
			
		||||
0,     CC,         9,          ".ls",
 | 
			
		||||
0,     CC,         10,         ".ge",
 | 
			
		||||
0,     CC,         11,         ".lt",
 | 
			
		||||
0,     CC,         12,         ".gt",
 | 
			
		||||
0,     CC,         13,         ".le",
 | 
			
		||||
0,     CC,         15,         ".f",
 | 
			
		||||
 | 
			
		||||
/* Special instructions */
 | 
			
		||||
 | 
			
		||||
0,     OP,                    B16(00000000,00000001),                  "nop",
 | 
			
		||||
0,     OP,                    B16(00000000,00001010),                  "rti",
 | 
			
		||||
 | 
			
		||||
0,     OP_BRANCH,             0,                                       "b",
 | 
			
		||||
0,     OP_BRANCHLINK,         0,                                       "bl",
 | 
			
		||||
0,     OP_ADDCMPB,            0,                                       "addcmpb",
 | 
			
		||||
 | 
			
		||||
0,     OP_ONELREG,            B16(00000000,10000000),                  "tbb",
 | 
			
		||||
0,     OP_ONELREG,            B16(00000000,10100000),                  "tbs",
 | 
			
		||||
 | 
			
		||||
0,     OP_ALU,                B8(00000000),                            "mov",
 | 
			
		||||
0,     OP_ALU,                B8(00000001),                            "cmn",
 | 
			
		||||
0,     OP_ALU,                B8(00000010),                            "add",
 | 
			
		||||
0,     OP_ALU,                B8(00000011),                            "bic",
 | 
			
		||||
0,     OP_ALU,                B8(00000100),                            "mul",
 | 
			
		||||
0,     OP_ALU,                B8(00000101),                            "eor",
 | 
			
		||||
0,     OP_ALU,                B8(00000110),                            "sub",
 | 
			
		||||
0,     OP_ALU,                B8(00000111),                            "and",
 | 
			
		||||
0,     OP_ALU,                B8(00001000),                            "mvn",
 | 
			
		||||
0,     OP_ALU,                B8(00001001),                            "ror",
 | 
			
		||||
0,     OP_ALU,                B8(00001010),                            "cmp",
 | 
			
		||||
0,     OP_ALU,                B8(00001011),                            "rsb",
 | 
			
		||||
0,     OP_ALU,                B8(00001100),                            "btst",
 | 
			
		||||
0,     OP_ALU,                B8(00001101),                            "or",
 | 
			
		||||
0,     OP_ALU,                B8(00001110),                            "extu",
 | 
			
		||||
0,     OP_ALU,                B8(00001111),                            "max",
 | 
			
		||||
0,     OP_ALU,                B8(00010000),                            "bset",
 | 
			
		||||
0,     OP_ALU,                B8(00010001),                            "min",
 | 
			
		||||
0,     OP_ALU,                B8(00010010),                            "bclr",
 | 
			
		||||
0,     OP_ALU,                B8(00010011),                            "adds2",
 | 
			
		||||
0,     OP_ALU,                B8(00010100),                            "bchg",
 | 
			
		||||
0,     OP_ALU,                B8(00010101),                            "adds4",
 | 
			
		||||
0,     OP_ALU,                B8(00010110),                            "adds8",
 | 
			
		||||
0,     OP_ALU,                B8(00010111),                            "adds16",
 | 
			
		||||
0,     OP_ALU,                B8(00011000),                            "exts",
 | 
			
		||||
0,     OP_ALU,                B8(00011001),                            "neg",
 | 
			
		||||
0,     OP_ALU,                B8(00011010),                            "lsr",
 | 
			
		||||
0,     OP_ALU,                B8(00011011),                            "log2",
 | 
			
		||||
0,     OP_ALU,                B8(00011100),                            "lsl",
 | 
			
		||||
0,     OP_ALU,                B8(00011101),                            "brev",
 | 
			
		||||
0,     OP_ALU,                B8(00011110),                            "asr",
 | 
			
		||||
0,     OP_ALU,                B8(00011111),                            "abs",
 | 
			
		||||
 | 
			
		||||
0,     OP_MISC,               B16(11001000,00000000),                  "fadd",
 | 
			
		||||
0,     OP_MISC,               B16(11001000,00100000),                  "fsub",
 | 
			
		||||
0,     OP_MISC,               B16(11001000,01000000),                  "fmul",
 | 
			
		||||
0,     OP_MISC,               B16(11001000,01100000),                  "fdiv",
 | 
			
		||||
0,     OP_MISC,               B16(11001000,10000000),                  "fcmp",
 | 
			
		||||
0,     OP_MISC,               B16(11001000,10100000),                  "fabs",
 | 
			
		||||
0,     OP_MISC,               B16(11001000,11000000),                  "frsb",
 | 
			
		||||
0,     OP_MISC,               B16(11001000,11100000),                  "fmax",
 | 
			
		||||
0,     OP_MISC,               B16(11001001,00000000),                  "frcp",
 | 
			
		||||
0,     OP_MISC,               B16(11001001,00100000),                  "frsqrt",
 | 
			
		||||
0,     OP_MISC,               B16(11001001,01000000),                  "fnmul",
 | 
			
		||||
0,     OP_MISC,               B16(11001001,01100000),                  "fmin",
 | 
			
		||||
0,     OP_MISC,               B16(11001001,10000000),                  "fld1",
 | 
			
		||||
0,     OP_MISC,               B16(11001001,10100000),                  "fld0",
 | 
			
		||||
0,     OP_MISC,               B16(11001001,11000000),                  "log2",
 | 
			
		||||
0,     OP_MISC,               B16(11001001,11100000),                  "exp2",
 | 
			
		||||
0,     OP_MISC,               B16(11000101,11100000),                  "adds256",
 | 
			
		||||
 | 
			
		||||
0,     OP_FLTCNV,             B16(11001010,00000000),                  "ftrunc",
 | 
			
		||||
0,     OP_FLTCNV,             B16(11001010,00100000),                  "floor",
 | 
			
		||||
0,     OP_FLTCNV,             B16(11001010,01000000),                  "flts",
 | 
			
		||||
0,     OP_FLTCNV,             B16(11001010,01100000),                  "fltu",
 | 
			
		||||
 | 
			
		||||
0,     OP_MISCL,              B16(11000100,10000000),                  "divs",
 | 
			
		||||
0,     OP_MISCL,              B16(11000100,11100000),                  "divu",
 | 
			
		||||
 | 
			
		||||
0,     OP_STACK,              B16(00000010,10000000),                  "push",
 | 
			
		||||
0,     OP_STACK,              B16(00000010,00000000),                  "pop",
 | 
			
		||||
 | 
			
		||||
0,     OP_MEM,                B8(00000000),                            "ld",
 | 
			
		||||
0,     OP_MEM,                B8(00000001),                            "st",
 | 
			
		||||
0,     OP_MEM,                B8(00000010),                            "ldh",
 | 
			
		||||
0,     OP_MEM,                B8(00000011),                            "sth",
 | 
			
		||||
0,     OP_MEM,                B8(00000100),                            "ldb",
 | 
			
		||||
0,     OP_MEM,                B8(00000101),                            "stb",
 | 
			
		||||
0,     OP_MEM,                B8(00000110),                            "ldhs",
 | 
			
		||||
0,     OP_MEM,                B8(00000111),                            "sths",
 | 
			
		||||
 | 
			
		||||
0,     OP_LEA,                0,                                       "lea",
 | 
			
		||||
							
								
								
									
										87
									
								
								mach/vc4/as/mach4.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								mach/vc4/as/mach4.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,87 @@
 | 
			
		|||
/*
 | 
			
		||||
 * VideoCore IV assembler for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
operation
 | 
			
		||||
	: OP                                   { emit2($1); }
 | 
			
		||||
 | 
			
		||||
	| OP_BRANCH GPR                        { emit2(B16(00000000,01000000) | ($2<<0)); }
 | 
			
		||||
	| OP_BRANCHLINK GPR                    { emit2(B16(00000000,01100000) | ($2<<0)); }
 | 
			
		||||
 | 
			
		||||
	| OP_BRANCH expr                       { branch_instr(0, ALWAYS, &$2); }
 | 
			
		||||
	| OP_BRANCHLINK expr                   { branch_instr(1, ALWAYS, &$2); }
 | 
			
		||||
	| OP_BRANCH CC expr                    { branch_instr(0, $2, &$3); }
 | 
			
		||||
	| OP_BRANCHLINK CC expr                { branch_instr(1, $2, &$3); }
 | 
			
		||||
 | 
			
		||||
	| OP_BRANCH GPR ',' GPR ',' expr       { branch_addcmp_lit_reg_instr(ALWAYS, $2, 0, $4, &$6); }
 | 
			
		||||
	| OP_BRANCH CC GPR ',' GPR ',' expr    { branch_addcmp_lit_reg_instr($2, $3, 0, $5, &$7); }
 | 
			
		||||
	| OP_BRANCH GPR ',' '#' absexp ',' expr { branch_addcmp_lit_lit_instr(ALWAYS, $2, 0, $5, &$7); }
 | 
			
		||||
	| OP_BRANCH CC GPR ',' '#' absexp ',' expr { branch_addcmp_lit_lit_instr($2, $3, 0, $6, &$8); }
 | 
			
		||||
	| OP_ADDCMPB GPR ',' GPR ',' GPR ',' expr { branch_addcmp_reg_reg_instr(ALWAYS, $2, $4, $6, &$8); }
 | 
			
		||||
	| OP_ADDCMPB CC GPR ',' GPR ',' GPR ',' expr { branch_addcmp_reg_reg_instr($2, $3, $5, $7, &$9); }
 | 
			
		||||
	| OP_ADDCMPB GPR ',' '#' absexp ',' GPR ',' expr { branch_addcmp_lit_reg_instr(ALWAYS, $2, $5, $7, &$9); }
 | 
			
		||||
	| OP_ADDCMPB CC GPR ',' '#' absexp ',' GPR ',' expr { branch_addcmp_lit_reg_instr($2, $3, $6, $8, &$10); }
 | 
			
		||||
	| OP_ADDCMPB GPR ',' GPR ',' '#' absexp ',' expr { branch_addcmp_reg_lit_instr(ALWAYS, $2, $4, $7, &$9); }
 | 
			
		||||
	| OP_ADDCMPB CC GPR ',' GPR ',' '#' absexp ',' expr { branch_addcmp_reg_lit_instr($2, $3, $5, $8, &$10); }
 | 
			
		||||
	| OP_ADDCMPB GPR ',' '#' absexp ',' '#' absexp ',' expr { branch_addcmp_lit_lit_instr(ALWAYS, $2, $5, $8, &$10); }
 | 
			
		||||
	| OP_ADDCMPB CC GPR ',' '#' absexp ',' '#' absexp ',' expr { branch_addcmp_lit_lit_instr($2, $3, $6, $9, &$11); }
 | 
			
		||||
 | 
			
		||||
	| OP_ONELREG GPR
 | 
			
		||||
	{
 | 
			
		||||
		if ($2 >= 0x10)
 | 
			
		||||
			serror("cannot use r16+ here");
 | 
			
		||||
		emit2($1 | ($2<<0));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	| OP_ALU GPR ',' GPR                   { alu_instr_reg($1, ALWAYS, $2, $2, $4); }
 | 
			
		||||
	| OP_ALU GPR ',' GPR ',' GPR           { alu_instr_reg($1, ALWAYS, $2, $4, $6); }
 | 
			
		||||
	| OP_ALU CC GPR ',' GPR                { alu_instr_reg($1, $2, $3, $3, $5); }
 | 
			
		||||
	| OP_ALU CC GPR ',' GPR ',' GPR        { alu_instr_reg($1, $2, $3, $5, $7); }
 | 
			
		||||
 | 
			
		||||
	| OP_ALU GPR ',' '#' absexp            { alu_instr_lit($1, ALWAYS, $2, $2, $5); }
 | 
			
		||||
	| OP_ALU GPR ',' GPR ',' '#' absexp    { alu_instr_lit($1, ALWAYS, $2, $4, $7); }
 | 
			
		||||
	| OP_ALU CC GPR ',' '#' absexp         { alu_instr_lit($1, $2, $3, $3, $6); }
 | 
			
		||||
	| OP_ALU CC GPR ',' GPR ',' '#' absexp { alu_instr_lit($1, $2, $3, $5, $8); }
 | 
			
		||||
 | 
			
		||||
	| OP_MISC GPR ',' GPR ',' GPR          { misc_instr_reg($1, ALWAYS, $2, $4, $6); }
 | 
			
		||||
	| OP_MISC CC GPR ',' GPR ',' GPR       { misc_instr_reg($1, $2, $3, $5, $7); }
 | 
			
		||||
 | 
			
		||||
	| OP_MISCL GPR ',' GPR ',' GPR         { misc_instr_reg($1, ALWAYS, $2, $4, $6); }
 | 
			
		||||
	| OP_MISCL CC GPR ',' GPR ',' GPR      { misc_instr_reg($1, $2, $3, $5, $7); }
 | 
			
		||||
	| OP_MISCL GPR ',' GPR ',' '#' absexp  { misc_instr_lit($1, ALWAYS, $2, $4, $7); }
 | 
			
		||||
	| OP_MISCL CC GPR ',' GPR ',' '#' absexp { misc_instr_lit($1, $2, $3, $5, $8); }
 | 
			
		||||
 | 
			
		||||
	| OP_STACK GPR                         { stack_instr($1, $2, $2, -1); }
 | 
			
		||||
	| OP_STACK GPR ',' GPR                 { stack_instr($1, $2, $2, $4); }
 | 
			
		||||
	| OP_STACK GPR '-' GPR                 { stack_instr($1, $2, $4, -1); }
 | 
			
		||||
	| OP_STACK GPR '-' GPR ',' GPR         { stack_instr($1, $2, $4, $6); }
 | 
			
		||||
 | 
			
		||||
	| OP_MEM GPR ',' '(' GPR ')'           { mem_instr($1, ALWAYS, $2, 0, $5); }
 | 
			
		||||
	| OP_MEM CC GPR ',' '(' GPR ')'        { mem_instr($1, $2, $3, 0, $6); }
 | 
			
		||||
	| OP_MEM GPR ',' absexp '(' GPR ')'    { mem_instr($1, ALWAYS, $2, $4, $6); }
 | 
			
		||||
	| OP_MEM CC GPR ',' absexp '(' GPR ')' { mem_instr($1, $2, $3, $5, $7); }
 | 
			
		||||
 | 
			
		||||
    | OP_MEM GPR ',' '(' GPR ',' GPR ')'   { mem_offset_instr($1, ALWAYS, $2, $5, $7); }
 | 
			
		||||
    | OP_MEM CC GPR ',' '(' GPR ',' GPR ')' { mem_offset_instr($1, $2, $3, $6, $8); }
 | 
			
		||||
 | 
			
		||||
    | OP_MEM GPR ',' '(' GPR ')' '+' '+'   { mem_postincr_instr($1, ALWAYS, $2, $5); }
 | 
			
		||||
    | OP_MEM CC GPR ',' '(' GPR ')' '+' '+' { mem_postincr_instr($1, $2, $3, $6); }
 | 
			
		||||
 | 
			
		||||
    | OP_MEM GPR ',' expr                  { mem_address_instr($1, $2, &$4); }
 | 
			
		||||
 | 
			
		||||
    | OP_LEA GPR ',' absexp '(' GPR ')'    { lea_stack_instr($2, $4, $6); }
 | 
			
		||||
	| OP_LEA GPR ',' expr                  { lea_address_instr($2, &$4); }
 | 
			
		||||
 | 
			
		||||
	| OP_FLTCNV GPR ',' GPR                { fltcnv_instr($1, ALWAYS, $2, $4, 0); }
 | 
			
		||||
	| OP_FLTCNV CC GPR ',' GPR             { fltcnv_instr($1, $2, $3, $5, 0); }
 | 
			
		||||
	| OP_FLTCNV GPR ',' GPR ',' shift '#' absexp { fltcnv_instr($1, ALWAYS, $2, $4, $8); }
 | 
			
		||||
	| OP_FLTCNV CC GPR ',' GPR ',' shift '#' absexp { fltcnv_instr($1, $2, $3, $5, $9); }
 | 
			
		||||
	;
 | 
			
		||||
 | 
			
		||||
shift
 | 
			
		||||
	: 'l' 's' 'r'
 | 
			
		||||
    | 'l' 's' 'l';
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										501
									
								
								mach/vc4/as/mach5.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										501
									
								
								mach/vc4/as/mach5.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,501 @@
 | 
			
		|||
/*
 | 
			
		||||
 * VideoCore IV assembler for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#define maskx(v, x) (v & ((1<<(x))-1))
 | 
			
		||||
 | 
			
		||||
static void toobig(void)
 | 
			
		||||
{
 | 
			
		||||
	serror("offset too big to encode into instruction");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Assemble an ALU instruction where rb is a register. */
 | 
			
		||||
 | 
			
		||||
void alu_instr_reg(quad op, int cc, int rd, int ra, int rb)
 | 
			
		||||
{
 | 
			
		||||
	/* Can we use short form? */
 | 
			
		||||
 | 
			
		||||
	if ((cc == ALWAYS) && (ra == rd) && (ra < 0x10) && (rb < 0x10))
 | 
			
		||||
	{
 | 
			
		||||
		emit2(B16(01000000,00000000) | (op<<8) | (rb<<4) | (rd<<0));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    /* Long form, then. */
 | 
			
		||||
 | 
			
		||||
    emit2(B16(11000000,00000000) | (op<<5) | (rd<<0));
 | 
			
		||||
    emit2(B16(00000000,00000000) | (ra<<11) | (cc<<7) | (rb<<0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Assemble an ALU instruction where rb is a literal. */
 | 
			
		||||
 | 
			
		||||
void alu_instr_lit(quad op, int cc, int rd, int ra, long value)
 | 
			
		||||
{
 | 
			
		||||
	/* 16 bit short form? */
 | 
			
		||||
 | 
			
		||||
	if ((cc == ALWAYS) && !(op & 1) && (value >= 0) && (value <= 0x1f) &&
 | 
			
		||||
	    (ra == rd) && (ra < 0x10))
 | 
			
		||||
	{
 | 
			
		||||
		emit2(B16(01100000,00000000) | (op<<8) | (value<<4) | (rd<<0));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* 32 bit medium form? */
 | 
			
		||||
 | 
			
		||||
    if ((value >= 0) && (value <= 0x1f))
 | 
			
		||||
    {
 | 
			
		||||
        emit2(B16(11000000,00000000) | (op<<5) | (rd<<0));
 | 
			
		||||
        emit2(B16(00000000,01000000) | (ra<<11) | (cc<<7) | (value<<0));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	/* Long form, then. */
 | 
			
		||||
 | 
			
		||||
	if (cc != ALWAYS)
 | 
			
		||||
		serror("cannot use condition codes with ALU literals this big");
 | 
			
		||||
 | 
			
		||||
	/* add is special. */
 | 
			
		||||
 | 
			
		||||
	if (op == B8(00000010))
 | 
			
		||||
		emit2(B16(11101100,00000000) | (ra<<5) | (rd<<0));
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (ra != rd)
 | 
			
		||||
			serror("can only use 2op form of ALU instructions with literals this big");
 | 
			
		||||
		emit2(B16(11101000,00000000) | (op<<5) | (rd<<0));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	emit4(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Miscellaneous instructions with three registers and a cc. */
 | 
			
		||||
 | 
			
		||||
void misc_instr_reg(quad op, int cc, int rd, int ra, int rb)
 | 
			
		||||
{
 | 
			
		||||
	emit2(op | (rd<<0));
 | 
			
		||||
	emit2(B16(00000000,00000000) | (ra<<11) | (cc<<7) | (rb<<0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Miscellaneous instructions with two registers, a literal, and a cc. */
 | 
			
		||||
 | 
			
		||||
void misc_instr_lit(quad op, int cc, int rd, int ra, quad value)
 | 
			
		||||
{
 | 
			
		||||
    if (value < 0x1f)
 | 
			
		||||
        serror("only constants from 0..31 can be used here");
 | 
			
		||||
 | 
			
		||||
	emit2(op | (rd<<0));
 | 
			
		||||
	emit2(B16(00000000,01000000) | (ra<<11) | (cc<<7) | (value<<0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Assemble a branch instruction. This may be a near branch into this
 | 
			
		||||
 * object file, or a far branch which requires a fixup. */
 | 
			
		||||
 | 
			
		||||
void branch_instr(int bl, int cc, struct expr_t* expr)
 | 
			
		||||
{
 | 
			
		||||
	quad pc = DOTVAL;
 | 
			
		||||
	quad type = expr->typ & S_TYP;
 | 
			
		||||
	int d;
 | 
			
		||||
 | 
			
		||||
	/* Sanity checking. */
 | 
			
		||||
 | 
			
		||||
	if (bl && (cc != ALWAYS))
 | 
			
		||||
		serror("can't use condition codes with bl");
 | 
			
		||||
	if (type == S_ABS)
 | 
			
		||||
		serror("can't use absolute addresses here");
 | 
			
		||||
 | 
			
		||||
	/* The VC4 branch instructions express distance in 2-byte
 | 
			
		||||
	 * words. */
 | 
			
		||||
 | 
			
		||||
	d = (int32_t)expr->val - (int32_t)pc;
 | 
			
		||||
	if ((pass == 2) && (d > 0) && !(expr->typ & S_DOT))
 | 
			
		||||
        d -= DOTGAIN;
 | 
			
		||||
	d /= 2;
 | 
			
		||||
 | 
			
		||||
    /* If this is a reference to code within this section, and it's
 | 
			
		||||
     * close enough to the program counter, we can use a short-
 | 
			
		||||
     * form instruction. */
 | 
			
		||||
 | 
			
		||||
    if (small(!bl && (type == DOTTYP) && fitx(d, 7), 2))
 | 
			
		||||
    {
 | 
			
		||||
		emit2(B16(00011000,00000000) | (cc<<7) | (d&0x7f));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Absolute addresses and references to other sections
 | 
			
		||||
	 * need the full 32 bits. */
 | 
			
		||||
 | 
			
		||||
	newrelo(expr->typ, RELOVC4|RELPC);
 | 
			
		||||
 | 
			
		||||
	if (bl)
 | 
			
		||||
	{
 | 
			
		||||
		quad v, hiv, lov;
 | 
			
		||||
 | 
			
		||||
		if (!fitx(d, 27))
 | 
			
		||||
			toobig();
 | 
			
		||||
 | 
			
		||||
		v = maskx(d, 27);
 | 
			
		||||
		hiv = v >> 23;
 | 
			
		||||
		lov = v & 0x007fffff;
 | 
			
		||||
		emit2(B16(10010000,10000000) | (lov>>16) | (hiv<<8));
 | 
			
		||||
		emit2(B16(00000000,00000000) | (lov&0xffff));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		quad v;
 | 
			
		||||
 | 
			
		||||
		if (!fitx(d, 23))
 | 
			
		||||
			toobig();
 | 
			
		||||
 | 
			
		||||
		v = maskx(d, 23);
 | 
			
		||||
		emit2(B16(10010000,00000000) | (cc<<8) | (v>>16));
 | 
			
		||||
		emit2(B16(00000000,00000000) | (v&0xffff));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Push/pop. */
 | 
			
		||||
 | 
			
		||||
void stack_instr(quad opcode, int loreg, int hireg, int extrareg)
 | 
			
		||||
{
 | 
			
		||||
    int b;
 | 
			
		||||
    int m;
 | 
			
		||||
 | 
			
		||||
    switch (loreg)
 | 
			
		||||
    {
 | 
			
		||||
        case 0: b = 0; break;
 | 
			
		||||
        case 6: b = 1; break;
 | 
			
		||||
        case 16: b = 2; break;
 | 
			
		||||
        case 24: b = 3; break;
 | 
			
		||||
 | 
			
		||||
        case 26: /* lr */
 | 
			
		||||
            extrareg = 26;
 | 
			
		||||
            hireg = loreg = -1;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
		case 31: /* pc */
 | 
			
		||||
			extrareg = 31;
 | 
			
		||||
			hireg = loreg = -1;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			serror("base register for push or pop may be only r0, r6, r16, r24, lr or pc");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (opcode & 0x0080)
 | 
			
		||||
	{
 | 
			
		||||
		/* Push */
 | 
			
		||||
		if (extrareg == 31)
 | 
			
		||||
			serror("cannot push pc");
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* Pop */
 | 
			
		||||
		if (extrareg == 26)
 | 
			
		||||
			serror("cannot pop lr");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (hireg < loreg)
 | 
			
		||||
		serror("invalid register range");
 | 
			
		||||
 | 
			
		||||
	if (hireg == -1)
 | 
			
		||||
	{
 | 
			
		||||
		b = 3;
 | 
			
		||||
		m = 15;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		m = hireg - loreg;
 | 
			
		||||
 | 
			
		||||
	emit2(opcode | (b<<5) | (m<<0) | ((extrareg != -1) ? 0x0100 : 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Memory operations where the offset is a fixed value (including zero). */
 | 
			
		||||
 | 
			
		||||
void mem_instr(quad opcode, int cc, int rd, long offset, int rs)
 | 
			
		||||
{
 | 
			
		||||
	quad uoffset = (quad) offset;
 | 
			
		||||
	int multiple4 = !(offset & 3);
 | 
			
		||||
	int intonly = ((opcode & B8(00000110)) == 0);
 | 
			
		||||
 | 
			
		||||
	/* If no CC, there are some special forms we can use. */
 | 
			
		||||
 | 
			
		||||
	if (cc == ALWAYS)
 | 
			
		||||
	{
 | 
			
		||||
		/* Very short form, special for stack offsets. */
 | 
			
		||||
 | 
			
		||||
		if (intonly && (rs == 25) && multiple4 && fitx(offset, 7) && (rd < 0x10))
 | 
			
		||||
		{
 | 
			
		||||
			quad o = maskx(offset, 7) / 4;
 | 
			
		||||
			emit2(B16(00000100,00000000) | (opcode<<9) | (o<<4) | (rd<<0));
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Slightly longer form for directly dereferencing via a register. */
 | 
			
		||||
 | 
			
		||||
		if ((rs < 0x10) && (rd < 0x10) && (offset == 0))
 | 
			
		||||
		{
 | 
			
		||||
			emit2(B16(00001000,00000000) | (opcode<<8) | (rs<<4) | (rd<<0));
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	    /* Integer only, but a limited offset. */
 | 
			
		||||
 | 
			
		||||
	    if (intonly && (uoffset <= 0x3f) && (rs < 0x10) && (rd < 0x10))
 | 
			
		||||
		{
 | 
			
		||||
			quad o = uoffset / 4;
 | 
			
		||||
			emit2(B16(00100000,00000000) | (opcode<<12) | (o<<8) |
 | 
			
		||||
				(rs<<4) | (rd<<0));
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Certain registers support 16-bit offsets. */
 | 
			
		||||
 | 
			
		||||
		if (fitx(offset, 16))
 | 
			
		||||
		{
 | 
			
		||||
			switch (rs)
 | 
			
		||||
			{
 | 
			
		||||
                case 0: opcode = B16(10101011,00000000) | (opcode<<5); goto specialreg;
 | 
			
		||||
                case 24: opcode = B16(10101000,00000000) | (opcode<<5); goto specialreg;
 | 
			
		||||
                case 25: opcode = B16(10101001,00000000) | (opcode<<5); goto specialreg;
 | 
			
		||||
                case 31: opcode = B16(10101010,00000000) | (opcode<<5); goto specialreg;
 | 
			
		||||
                default: break;
 | 
			
		||||
 | 
			
		||||
                specialreg:
 | 
			
		||||
                {
 | 
			
		||||
                    quad o = maskx(offset, 16);
 | 
			
		||||
                    emit2(opcode | (rd<<0));
 | 
			
		||||
                    emit2(o);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        /* 12-bit displacements. */
 | 
			
		||||
 | 
			
		||||
        if (fitx(offset, 12))
 | 
			
		||||
        {
 | 
			
		||||
        	quad looffset = maskx(offset, 11);
 | 
			
		||||
        	quad hioffset = (offset >> 11) & 1;
 | 
			
		||||
 | 
			
		||||
        	emit2(B16(10100010,00000000) | (opcode<<5) | (rd<<0) | (hioffset<<8));
 | 
			
		||||
        	emit2(B16(00000000,00000000) | (rs<<11) | (looffset<<0));
 | 
			
		||||
        	return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Everything else uses Very Long Form. */
 | 
			
		||||
 | 
			
		||||
		if (!fitx(offset, 27))
 | 
			
		||||
			serror("offset will not fit into load/store instruction");
 | 
			
		||||
 | 
			
		||||
		if (rs == 31)
 | 
			
		||||
			opcode = B16(11100111,00000000) | (opcode<<5);
 | 
			
		||||
		else
 | 
			
		||||
			opcode = B16(11100110,00000000) | (opcode<<5);
 | 
			
		||||
 | 
			
		||||
		emit2(opcode | (rd<<0));
 | 
			
		||||
		emit4((rs<<27) | maskx(offset, 27));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Now we're on to load/store instructions with ccs. */
 | 
			
		||||
 | 
			
		||||
	if (uoffset <= 0x1f)
 | 
			
		||||
	{
 | 
			
		||||
		emit2(B16(10100000,00000000) | (opcode<<5) | (rd<<0));
 | 
			
		||||
		emit2(B16(00000000,01000000) | (rs<<11) | (cc<<7) | (uoffset<<0));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* No encoding for this instruction. */
 | 
			
		||||
 | 
			
		||||
	serror("invalid load/store instruction");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Memory operations where the destination address is a sum of two
 | 
			
		||||
 * registers. */
 | 
			
		||||
 | 
			
		||||
void mem_offset_instr(quad opcode, int cc, int rd, int ra, int rb)
 | 
			
		||||
{
 | 
			
		||||
    emit2(B16(10100000,00000000) | (opcode<<5) | (rd<<0));
 | 
			
		||||
    emit2(B16(00000000,00000000) | (ra<<11) | (cc<<7) | (rb<<0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Memory operations with postincrement. */
 | 
			
		||||
 | 
			
		||||
void mem_postincr_instr(quad opcode, int cc, int rd, int rs)
 | 
			
		||||
{
 | 
			
		||||
    emit2(B16(10100101,00000000) | (opcode<<5) | (rd<<0));
 | 
			
		||||
    emit2(B16(00000000,00000000) | (rs<<11) | (cc<<7));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Memory operations where the destination is an address literal. */
 | 
			
		||||
 | 
			
		||||
void mem_address_instr(quad opcode, int rd, struct expr_t* expr)
 | 
			
		||||
{
 | 
			
		||||
	static const char sizes[] = {4, 4, 2, 2, 1, 1, 2, 2};
 | 
			
		||||
	int size = sizes[opcode];
 | 
			
		||||
	quad type = expr->typ & S_TYP;
 | 
			
		||||
	int d, scaledd;
 | 
			
		||||
 | 
			
		||||
	/* Sanity checking. */
 | 
			
		||||
 | 
			
		||||
	if (type == S_ABS)
 | 
			
		||||
		serror("can't use absolute addresses here");
 | 
			
		||||
 | 
			
		||||
	d = expr->val - DOTVAL;
 | 
			
		||||
	if ((pass == 2) && (d > 0) && !(expr->typ & S_DOT))
 | 
			
		||||
        d -= DOTGAIN;
 | 
			
		||||
    scaledd = d/size;
 | 
			
		||||
 | 
			
		||||
    /* If this is a reference to an address within this section, and
 | 
			
		||||
     * it's close enough to the program counter, we can use a
 | 
			
		||||
     * shorter instruction. */
 | 
			
		||||
 | 
			
		||||
	if (small((type==DOTTYP) && fitx(scaledd, 16), 2))
 | 
			
		||||
	{
 | 
			
		||||
        emit2(B16(10101010,00000000) | (opcode<<5) | (rd<<0));
 | 
			
		||||
        emit2(scaledd);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	/* Otherwise we need the full 48 bits. */
 | 
			
		||||
 | 
			
		||||
	newrelo(expr->typ, RELOVC4|RELPC);
 | 
			
		||||
 | 
			
		||||
	/* VC4 relocations store the PC-relative delta into the
 | 
			
		||||
	 * destination section in the instruction data. The linker will
 | 
			
		||||
	 * massage this, and scale it appropriately. */
 | 
			
		||||
 | 
			
		||||
    if (!fitx(d, 27))
 | 
			
		||||
		toobig();
 | 
			
		||||
 | 
			
		||||
    emit2(B16(11100111,00000000) | (opcode<<5) | (rd<<0));
 | 
			
		||||
    emit4((31<<27) | maskx(d, 27));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Common code for handling addcmp: merge in as much of expr as will fit to
 | 
			
		||||
 * the second pair of the addcmp opcode. */
 | 
			
		||||
 | 
			
		||||
static void branch_addcmp_common(quad opcode, int bits, struct expr_t* expr)
 | 
			
		||||
{
 | 
			
		||||
	quad type = expr->typ & S_TYP;
 | 
			
		||||
	int d;
 | 
			
		||||
 | 
			
		||||
	if ((pass>0) && (type != DOTTYP))
 | 
			
		||||
		serror("can't use this type of branch to jump outside the section");
 | 
			
		||||
 | 
			
		||||
	/* The VC4 branch instructions express distance in 2-byte
 | 
			
		||||
	 * words. */
 | 
			
		||||
 | 
			
		||||
	d = (expr->val - DOTVAL-2 + 4);
 | 
			
		||||
	if ((pass == 2) && (d > 0) && !(expr->typ & S_DOT))
 | 
			
		||||
        d -= DOTGAIN;
 | 
			
		||||
    d /= 2;
 | 
			
		||||
 | 
			
		||||
	if ((pass == 2) && !fitx(d, bits))
 | 
			
		||||
		serror("target of branch is too far away");
 | 
			
		||||
 | 
			
		||||
	emit2(opcode | maskx(d, bits));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void branch_addcmp_reg_reg_instr(int cc, int rd, int ra, int rs, struct expr_t* expr)
 | 
			
		||||
{
 | 
			
		||||
    if ((rd >= 0x10) || (ra >= 0x10) || (rs >= 0x10))
 | 
			
		||||
        serror("can only use r0-r15 in this instruction");
 | 
			
		||||
 | 
			
		||||
	emit2(B16(10000000,00000000) | (cc<<8) | (ra<<4) | (rd<<0));
 | 
			
		||||
	branch_addcmp_common(B16(00000000,00000000) | (rs<<10), 10, expr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void branch_addcmp_lit_reg_instr(int cc, int rd, long va, int rs, struct expr_t* expr)
 | 
			
		||||
{
 | 
			
		||||
    if ((rd >= 0x10) || (rs >= 0x10))
 | 
			
		||||
        serror("can only use r0-r15 in this instruction");
 | 
			
		||||
 | 
			
		||||
	if (!fitx(va, 4))
 | 
			
		||||
		serror("value too big to encode into instruction");
 | 
			
		||||
    va = maskx(va, 4);
 | 
			
		||||
 | 
			
		||||
    emit2(B16(10000000,00000000) | (cc<<8) | (va<<4) | (rd<<0));
 | 
			
		||||
    branch_addcmp_common(B16(01000000,00000000) | (rs<<10), 10, expr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void branch_addcmp_reg_lit_instr(int cc, int rd, int ra, long vs, struct expr_t* expr)
 | 
			
		||||
{
 | 
			
		||||
    if ((rd >= 0x10) || (ra >= 0x10))
 | 
			
		||||
        serror("can only use r0-r15 in this instruction");
 | 
			
		||||
 | 
			
		||||
	if (!fitx(vs, 6))
 | 
			
		||||
		serror("value too big to encode into instruction");
 | 
			
		||||
	vs = maskx(vs, 6);
 | 
			
		||||
 | 
			
		||||
	emit2(B16(10000000,00000000) | (cc<<8) | (ra<<4) | (rd<<0));
 | 
			
		||||
	branch_addcmp_common(B16(10000000,00000000) | (vs<<8), 8, expr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void branch_addcmp_lit_lit_instr(int cc, int rd, long va, long vs, struct expr_t* expr)
 | 
			
		||||
{
 | 
			
		||||
    if (rd >= 0x10)
 | 
			
		||||
        serror("can only use r0-r15 in this instruction");
 | 
			
		||||
 | 
			
		||||
	if (!fitx(va, 4) || !fitx(vs, 6))
 | 
			
		||||
		serror("value too big to encode into instruction");
 | 
			
		||||
	va = maskx(va, 4);
 | 
			
		||||
	vs = maskx(vs, 6);
 | 
			
		||||
 | 
			
		||||
	emit2(B16(10000000,00000000) | (cc<<8) | (va<<4) | (rd<<0));
 | 
			
		||||
	branch_addcmp_common(B16(11000000,00000000) | (vs<<8), 8, expr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* lea, where the source is relative to the stack. */
 | 
			
		||||
 | 
			
		||||
void lea_stack_instr(int rd, long va, int rs)
 | 
			
		||||
{
 | 
			
		||||
    if (rs != 25)
 | 
			
		||||
        serror("source register must be sp");
 | 
			
		||||
 | 
			
		||||
	va /= 4;
 | 
			
		||||
	if (!fitx(va, 6))
 | 
			
		||||
		serror("offset too big to encode in instruction");
 | 
			
		||||
	va = maskx(va, 6);
 | 
			
		||||
 | 
			
		||||
	emit2(B16(00010000,00000000) | (rd<<0) | (va<<5));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* lea, where the source is an address. */
 | 
			
		||||
 | 
			
		||||
void lea_address_instr(int rd, struct expr_t* expr)
 | 
			
		||||
{
 | 
			
		||||
	quad pc = DOTVAL;
 | 
			
		||||
	quad type = expr->typ & S_TYP;
 | 
			
		||||
	int d = expr->val - pc;
 | 
			
		||||
 | 
			
		||||
	if ((pass == 2) && (d > 0) && !(expr->typ & S_DOT))
 | 
			
		||||
	    d -= DOTGAIN;
 | 
			
		||||
 | 
			
		||||
	if (type == S_ABS)
 | 
			
		||||
		serror("can't use absolute addresses here");
 | 
			
		||||
 | 
			
		||||
	newrelo(expr->typ, RELOVC4|RELPC);
 | 
			
		||||
 | 
			
		||||
	/* VC4 relocations store the PC-relative delta into the
 | 
			
		||||
	 * destination section in the instruction data. The linker will
 | 
			
		||||
	 * massage this, and scale it appropriately. */
 | 
			
		||||
 | 
			
		||||
	emit2(B16(11100101,00000000) | (rd<<0));
 | 
			
		||||
	emit4(expr->val - pc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Floating point conversion opcodes (ftrunc, floor, flts, fltu). */
 | 
			
		||||
 | 
			
		||||
void fltcnv_instr(quad opcode, int cc, int rd, int ra, quad shift)
 | 
			
		||||
{
 | 
			
		||||
	fitx(shift, 6);
 | 
			
		||||
 | 
			
		||||
	emit2(opcode | (rd<<0));
 | 
			
		||||
	emit2(B16(00000000,01000000) | (ra<<11) | (cc<<7) | shift);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								mach/vc4/build.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								mach/vc4/build.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
arch-libem-vc4 := \
 | 
			
		||||
	csa.s \
 | 
			
		||||
	csb.s
 | 
			
		||||
 | 
			
		||||
arch-libend-vc4 = \
 | 
			
		||||
	edata.s \
 | 
			
		||||
	em_end.s \
 | 
			
		||||
	end.s \
 | 
			
		||||
	etext.s
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								mach/vc4/libem/.distr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								mach/vc4/libem/.distr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
csa.s
 | 
			
		||||
csb.s
 | 
			
		||||
videocore.h
 | 
			
		||||
							
								
								
									
										36
									
								
								mach/vc4/libem/csa.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								mach/vc4/libem/csa.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * VideoCore IV support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "videocore.h"
 | 
			
		||||
 | 
			
		||||
.define	.csa
 | 
			
		||||
.sect .data
 | 
			
		||||
.csa:
 | 
			
		||||
	! on entry:
 | 
			
		||||
	!   r0 = un-fixed-up descriptor
 | 
			
		||||
	!   r1 = value
 | 
			
		||||
	add r0, gp
 | 
			
		||||
 | 
			
		||||
	ld r2, 4 (r0)            ! check lower bound
 | 
			
		||||
 | 
			
		||||
	b.lo r1, r2, default     ! jump to default if r1 < r2
 | 
			
		||||
 | 
			
		||||
	sub r1, r2               ! adjust value to be 0-based
 | 
			
		||||
 | 
			
		||||
	ld r2, 8 (r0)            ! check upper bound
 | 
			
		||||
	b.hi r1, r2, default     ! jump to default if r1 > r2
 | 
			
		||||
 | 
			
		||||
    add r1, #3
 | 
			
		||||
go:
 | 
			
		||||
    ld r1, (r0, r1)          ! load destination address
 | 
			
		||||
    add r1, gp
 | 
			
		||||
    b r1                     ! ...and go
 | 
			
		||||
 | 
			
		||||
default:
 | 
			
		||||
	mov r1, #0               ! index of default value
 | 
			
		||||
	b go
 | 
			
		||||
							
								
								
									
										33
									
								
								mach/vc4/libem/csb.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								mach/vc4/libem/csb.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * VideoCore IV support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "videocore.h"
 | 
			
		||||
 | 
			
		||||
.define	.csb
 | 
			
		||||
.sect .data
 | 
			
		||||
.csb:
 | 
			
		||||
	! on entry:
 | 
			
		||||
	!   r0 = un-fixed-up descriptor
 | 
			
		||||
	!   r1 = value
 | 
			
		||||
	add r0, gp               ! r0 = fixed up descriptor
 | 
			
		||||
 | 
			
		||||
	adds8 r2, r0, #1         ! r2 = moving pointer
 | 
			
		||||
	ld r3, 4 (r0)            ! r3 = count
 | 
			
		||||
	adds8 r3, r0, r3         ! r3 = end ptr
 | 
			
		||||
 | 
			
		||||
loop:
 | 
			
		||||
	ld r4, (r2)++
 | 
			
		||||
	b.eq r4, r1, matched      ! r2 points at matching addr
 | 
			
		||||
	addcmpb.le r2, #4, r3, loop
 | 
			
		||||
notmatched:
 | 
			
		||||
	mov r2, r0               ! r2 points at default jump
 | 
			
		||||
matched:
 | 
			
		||||
	ld r2, (r2)              ! load destination address
 | 
			
		||||
    add r2, gp               ! fix up r2
 | 
			
		||||
    b r2                     ! ...and go
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								mach/vc4/libem/videocore.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								mach/vc4/libem/videocore.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * VideoCore IV support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
! Declare segments (the order is important).
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
 | 
			
		||||
#define gp r15
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								mach/vc4/libend/.distr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								mach/vc4/libend/.distr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
edata.s
 | 
			
		||||
em_end.s
 | 
			
		||||
end.s
 | 
			
		||||
etext.s
 | 
			
		||||
							
								
								
									
										15
									
								
								mach/vc4/libend/edata.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								mach/vc4/libend/edata.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * VideoCore IV support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
.define	_edata
 | 
			
		||||
.sect .data
 | 
			
		||||
_edata:
 | 
			
		||||
							
								
								
									
										24
									
								
								mach/vc4/libend/em_end.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								mach/vc4/libend/em_end.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * VideoCore IV support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
.sect .end ! only for declaration of _end, __end and endbss.
 | 
			
		||||
.define	endtext, endrom, enddata, endbss, __end
 | 
			
		||||
 | 
			
		||||
	.sect .text
 | 
			
		||||
endtext:
 | 
			
		||||
	.sect .rom
 | 
			
		||||
endrom:
 | 
			
		||||
	.sect .data
 | 
			
		||||
enddata:
 | 
			
		||||
	.sect .end
 | 
			
		||||
__end:
 | 
			
		||||
endbss:
 | 
			
		||||
							
								
								
									
										15
									
								
								mach/vc4/libend/end.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								mach/vc4/libend/end.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * VideoCore IV support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
.define	_end
 | 
			
		||||
.sect .end ! only for declaration of _end, __end and endbss.
 | 
			
		||||
_end:
 | 
			
		||||
							
								
								
									
										15
									
								
								mach/vc4/libend/etext.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								mach/vc4/libend/etext.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * VideoCore IV support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
.define	_etext
 | 
			
		||||
.sect .text
 | 
			
		||||
_etext:
 | 
			
		||||
							
								
								
									
										3
									
								
								mach/vc4/ncg/.distr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								mach/vc4/ncg/.distr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
mach.c
 | 
			
		||||
mach.h
 | 
			
		||||
table
 | 
			
		||||
							
								
								
									
										86
									
								
								mach/vc4/ncg/mach.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								mach/vc4/ncg/mach.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
/*
 | 
			
		||||
 * VideoCore IV code generator for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
int framesize;
 | 
			
		||||
 | 
			
		||||
/* Write out a constant data section. */
 | 
			
		||||
 | 
			
		||||
con_part(int sz, word w)
 | 
			
		||||
{
 | 
			
		||||
	while (part_size % sz)
 | 
			
		||||
		part_size++;
 | 
			
		||||
	if (part_size == TEM_WSIZE)
 | 
			
		||||
		part_flush();
 | 
			
		||||
	if (sz == 1 || sz == 2) {
 | 
			
		||||
		w &= (sz == 1 ? 0xFF : 0xFFFF);
 | 
			
		||||
		w <<= 8 * part_size;
 | 
			
		||||
		part_word |= w;
 | 
			
		||||
	} else {
 | 
			
		||||
		assert(sz == 4);
 | 
			
		||||
		part_word = w;
 | 
			
		||||
	}
 | 
			
		||||
	part_size += sz;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
con_mult(word sz)
 | 
			
		||||
{
 | 
			
		||||
	if (argval != 4)
 | 
			
		||||
		fatal("bad icon/ucon size");
 | 
			
		||||
	fprintf(codefile,".data4 %s\n", str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define CODE_GENERATOR  
 | 
			
		||||
#define IEEEFLOAT  
 | 
			
		||||
#define FL_MSL_AT_LOW_ADDRESS	0
 | 
			
		||||
#define FL_MSW_AT_LOW_ADDRESS	0
 | 
			
		||||
#define FL_MSB_AT_LOW_ADDRESS	0
 | 
			
		||||
#include <con_float>
 | 
			
		||||
 | 
			
		||||
void prolog(full nlocals)
 | 
			
		||||
{
 | 
			
		||||
	int ss = nlocals + 8;
 | 
			
		||||
	fprintf(codefile, "push fp, lr\n");
 | 
			
		||||
	fprintf(codefile, "mov fp, sp\n");
 | 
			
		||||
	if (nlocals > 0)
 | 
			
		||||
		fprintf(codefile, "sub sp, #%d\n", nlocals);
 | 
			
		||||
 | 
			
		||||
	framesize = nlocals;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mes(word type)
 | 
			
		||||
{
 | 
			
		||||
	int argt ;
 | 
			
		||||
 | 
			
		||||
	switch ( (int)type ) {
 | 
			
		||||
	case ms_ext :
 | 
			
		||||
		for (;;) {
 | 
			
		||||
			switch ( argt=getarg(
 | 
			
		||||
			    ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
 | 
			
		||||
			case sp_cend :
 | 
			
		||||
				return ;
 | 
			
		||||
			default:
 | 
			
		||||
				strarg(argt) ;
 | 
			
		||||
				fprintf(codefile,".define %s\n",argstr) ;
 | 
			
		||||
				break ;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	default :
 | 
			
		||||
		while ( getarg(any_ptyp) != sp_cend ) ;
 | 
			
		||||
		break ;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *segname[] = {
 | 
			
		||||
	".sect .text",
 | 
			
		||||
	".sect .data",
 | 
			
		||||
	".sect .rom",
 | 
			
		||||
	".sect .bss"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								mach/vc4/ncg/mach.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								mach/vc4/ncg/mach.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
/*
 | 
			
		||||
 * VideoCore IV code generator for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define ex_ap(y)        fprintf(codefile,".extern %s\n",y)
 | 
			
		||||
#define in_ap(y)        /* nothing */
 | 
			
		||||
 | 
			
		||||
#define newilb(x)       fprintf(codefile,"%s:\n",x)
 | 
			
		||||
#define newdlb(x)       fprintf(codefile,"%s:\n",x)
 | 
			
		||||
#define dlbdlb(x,y)     fprintf(codefile,"%s = %s\n",x,y)
 | 
			
		||||
#define newlbss(l,x)       fprintf(codefile,".comm %s,%u\n",l,x);
 | 
			
		||||
 | 
			
		||||
#define cst_fmt         "%d"
 | 
			
		||||
#define off_fmt         "%d"
 | 
			
		||||
#define ilb_fmt         "I%x_%x"
 | 
			
		||||
#define dlb_fmt         "_%d"
 | 
			
		||||
#define hol_fmt         "hol%d"
 | 
			
		||||
 | 
			
		||||
#define hol_off         "%ld+hol%d"
 | 
			
		||||
 | 
			
		||||
#define con_cst(x)      fprintf(codefile,".data4\t%ld\n",x)
 | 
			
		||||
#define con_ilb(x)      fprintf(codefile,".data4\t%s\n",x)
 | 
			
		||||
#define con_dlb(x)      fprintf(codefile,".data4\t%s\n",x)
 | 
			
		||||
 | 
			
		||||
#define fmt_id(sf, st)	sprintf(st,"_%s",sf)
 | 
			
		||||
 | 
			
		||||
#define modhead	".sect .text; .sect .rom; .sect .data; .sect .bss\n"
 | 
			
		||||
 | 
			
		||||
#define BSS_INIT        0
 | 
			
		||||
							
								
								
									
										1560
									
								
								mach/vc4/ncg/table
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1560
									
								
								mach/vc4/ncg/table
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										362
									
								
								mach/vc4/test/opcodes.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										362
									
								
								mach/vc4/test/opcodes.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,362 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * VideoCore IV assembler test file
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
.sect .text
 | 
			
		||||
 | 
			
		||||
main:
 | 
			
		||||
	nop
 | 
			
		||||
	rti
 | 
			
		||||
 | 
			
		||||
	b r0
 | 
			
		||||
	b r31
 | 
			
		||||
	bl r0
 | 
			
		||||
	bl r31
 | 
			
		||||
	tbb r0
 | 
			
		||||
	tbb r15
 | 
			
		||||
	tbs r0
 | 
			
		||||
	tbs r15
 | 
			
		||||
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	mov r0, r1
 | 
			
		||||
    cmn r0, r1
 | 
			
		||||
    add r0, r1
 | 
			
		||||
	bic r0, r1
 | 
			
		||||
	mul r0, r1
 | 
			
		||||
	eor r0, r1
 | 
			
		||||
	sub r0, r1
 | 
			
		||||
	and r0, r1
 | 
			
		||||
	mvn r0, r1
 | 
			
		||||
	ror r0, r1
 | 
			
		||||
	cmp r0, r1
 | 
			
		||||
	rsb r0, r1
 | 
			
		||||
	btst r0, r1
 | 
			
		||||
	or r0, r1
 | 
			
		||||
	extu r0, r1
 | 
			
		||||
	max r0, r1
 | 
			
		||||
	bset r0, r1
 | 
			
		||||
	min r0, r1
 | 
			
		||||
	bclr r0, r1
 | 
			
		||||
	adds2 r0, r1
 | 
			
		||||
	bchg r0, r1
 | 
			
		||||
	adds4 r0, r1
 | 
			
		||||
	adds8 r0, r1
 | 
			
		||||
	adds16 r0, r1
 | 
			
		||||
	exts r0, r1
 | 
			
		||||
	neg r0, r1
 | 
			
		||||
	lsr r0, r1
 | 
			
		||||
	clz r0, r1
 | 
			
		||||
	lsl r0, r1
 | 
			
		||||
	brev r0, r1
 | 
			
		||||
	asr r0, r1
 | 
			
		||||
	abs r0, r1
 | 
			
		||||
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	mov.f r0, r1
 | 
			
		||||
    cmn.f r0, r1
 | 
			
		||||
    add.f r0, r1
 | 
			
		||||
	bic.f r0, r1
 | 
			
		||||
	mul.f r0, r1
 | 
			
		||||
	eor.f r0, r1
 | 
			
		||||
	sub.f r0, r1
 | 
			
		||||
	and.f r0, r1
 | 
			
		||||
	mvn.f r0, r1
 | 
			
		||||
	ror.f r0, r1
 | 
			
		||||
	cmp.f r0, r1
 | 
			
		||||
	rsb.f r0, r1
 | 
			
		||||
	btst.f r0, r1
 | 
			
		||||
	or.f r0, r1
 | 
			
		||||
	extu.f r0, r1
 | 
			
		||||
	max.f r0, r1
 | 
			
		||||
	bset.f r0, r1
 | 
			
		||||
	min.f r0, r1
 | 
			
		||||
	bclr.f r0, r1
 | 
			
		||||
	adds2.f r0, r1
 | 
			
		||||
	bchg.f r0, r1
 | 
			
		||||
	adds4.f r0, r1
 | 
			
		||||
	adds8.f r0, r1
 | 
			
		||||
	adds16.f r0, r1
 | 
			
		||||
	exts.f r0, r1
 | 
			
		||||
	neg.f r0, r1
 | 
			
		||||
	lsr.f r0, r1
 | 
			
		||||
	clz.f r0, r1
 | 
			
		||||
	lsl.f r0, r1
 | 
			
		||||
	brev.f r0, r1
 | 
			
		||||
	asr.f r0, r1
 | 
			
		||||
	abs.f r0, r1
 | 
			
		||||
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	mov r0, r1, r2
 | 
			
		||||
    cmn r0, r1, r2
 | 
			
		||||
    add r0, r1, r2
 | 
			
		||||
	bic r0, r1, r2
 | 
			
		||||
	mul r0, r1, r2
 | 
			
		||||
	eor r0, r1, r2
 | 
			
		||||
	sub r0, r1, r2
 | 
			
		||||
	and r0, r1, r2
 | 
			
		||||
	mvn r0, r1, r2
 | 
			
		||||
	ror r0, r1, r2
 | 
			
		||||
	cmp r0, r1, r2
 | 
			
		||||
	rsb r0, r1, r2
 | 
			
		||||
	btst r0, r1, r2
 | 
			
		||||
	or r0, r1, r2
 | 
			
		||||
	extu r0, r1, r2
 | 
			
		||||
	max r0, r1, r2
 | 
			
		||||
	bset r0, r1, r2
 | 
			
		||||
	min r0, r1, r2
 | 
			
		||||
	bclr r0, r1, r2
 | 
			
		||||
	adds2 r0, r1, r2
 | 
			
		||||
	bchg r0, r1, r2
 | 
			
		||||
	adds4 r0, r1, r2
 | 
			
		||||
	adds8 r0, r1, r2
 | 
			
		||||
	adds16 r0, r1, r2
 | 
			
		||||
	exts r0, r1, r2
 | 
			
		||||
	neg r0, r1, r2
 | 
			
		||||
	lsr r0, r1, r2
 | 
			
		||||
	clz r0, r1, r2
 | 
			
		||||
	lsl r0, r1, r2
 | 
			
		||||
	brev r0, r1, r2
 | 
			
		||||
	asr r0, r1, r2
 | 
			
		||||
	abs r0, r1, r2
 | 
			
		||||
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	mov r0, #0x1f
 | 
			
		||||
    cmn r0, #0x1f
 | 
			
		||||
    add r0, #0x1f
 | 
			
		||||
	bic r0, #0x1f
 | 
			
		||||
	mul r0, #0x1f
 | 
			
		||||
	eor r0, #0x1f
 | 
			
		||||
	sub r0, #0x1f
 | 
			
		||||
	and r0, #0x1f
 | 
			
		||||
	mvn r0, #0x1f
 | 
			
		||||
	ror r0, #0x1f
 | 
			
		||||
	cmp r0, #0x1f
 | 
			
		||||
	rsb r0, #0x1f
 | 
			
		||||
	btst r0, #0x1f
 | 
			
		||||
	or r0, #0x1f
 | 
			
		||||
	extu r0, #0x1f
 | 
			
		||||
	max r0, #0x1f
 | 
			
		||||
	bset r0, #0x1f
 | 
			
		||||
	min r0, #0x1f
 | 
			
		||||
	bclr r0, #0x1f
 | 
			
		||||
	adds2 r0, #0x1f
 | 
			
		||||
	bchg r0, #0x1f
 | 
			
		||||
	adds4 r0, #0x1f
 | 
			
		||||
	adds8 r0, #0x1f
 | 
			
		||||
	adds16 r0, #0x1f
 | 
			
		||||
	exts r0, #0x1f
 | 
			
		||||
	neg r0, #0x1f
 | 
			
		||||
	lsr r0, #0x1f
 | 
			
		||||
	clz r0, #0x1f
 | 
			
		||||
	lsl r0, #0x1f
 | 
			
		||||
	brev r0, #0x1f
 | 
			
		||||
	asr r0, #0x1f
 | 
			
		||||
	abs r0, #0x1f
 | 
			
		||||
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	mov.f r0, #0x1f
 | 
			
		||||
    cmn.f r0, #0x1f
 | 
			
		||||
    add.f r0, #0x1f
 | 
			
		||||
	bic.f r0, #0x1f
 | 
			
		||||
	mul.f r0, #0x1f
 | 
			
		||||
	eor.f r0, #0x1f
 | 
			
		||||
	sub.f r0, #0x1f
 | 
			
		||||
	and.f r0, #0x1f
 | 
			
		||||
	mvn.f r0, #0x1f
 | 
			
		||||
	ror.f r0, #0x1f
 | 
			
		||||
	cmp.f r0, #0x1f
 | 
			
		||||
	rsb.f r0, #0x1f
 | 
			
		||||
	btst.f r0, #0x1f
 | 
			
		||||
	or.f r0, #0x1f
 | 
			
		||||
	extu.f r0, #0x1f
 | 
			
		||||
	max.f r0, #0x1f
 | 
			
		||||
	bset.f r0, #0x1f
 | 
			
		||||
	min.f r0, #0x1f
 | 
			
		||||
	bclr.f r0, #0x1f
 | 
			
		||||
	adds2.f r0, #0x1f
 | 
			
		||||
	bchg.f r0, #0x1f
 | 
			
		||||
	adds4.f r0, #0x1f
 | 
			
		||||
	adds8.f r0, #0x1f
 | 
			
		||||
	adds16.f r0, #0x1f
 | 
			
		||||
	exts.f r0, #0x1f
 | 
			
		||||
	neg.f r0, #0x1f
 | 
			
		||||
	lsr.f r0, #0x1f
 | 
			
		||||
	clz.f r0, #0x1f
 | 
			
		||||
	lsl.f r0, #0x1f
 | 
			
		||||
	brev.f r0, #0x1f
 | 
			
		||||
	asr.f r0, #0x1f
 | 
			
		||||
	abs.f r0, #0x1f
 | 
			
		||||
 | 
			
		||||
	add r0, #0x12345678
 | 
			
		||||
	add r0, r1, #0x12345678
 | 
			
		||||
	sub r0, #0x12345678
 | 
			
		||||
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	fadd r0, r1, r2
 | 
			
		||||
	fsub r0, r1, r2
 | 
			
		||||
	fmul r0, r1, r2
 | 
			
		||||
	fdiv r0, r1, r2
 | 
			
		||||
	fcmp r0, r1, r2
 | 
			
		||||
	fabs r0, r1, r2
 | 
			
		||||
	frsb r0, r1, r2
 | 
			
		||||
	fmax r0, r1, r2
 | 
			
		||||
	frcp r0, r1, r2
 | 
			
		||||
	frsqrt r0, r1, r2
 | 
			
		||||
	fnmul r0, r1, r2
 | 
			
		||||
	fmin r0, r1, r2
 | 
			
		||||
	fld1 r0, r1, r2
 | 
			
		||||
	fld0 r0, r1, r2
 | 
			
		||||
	log2 r0, r1, r2
 | 
			
		||||
	exp2 r0, r1, r2
 | 
			
		||||
	divs r0, r1, r2
 | 
			
		||||
	divu r0, r1, r2
 | 
			
		||||
	divs r0, r1, #31
 | 
			
		||||
	divu r0, r1, #31
 | 
			
		||||
	adds256 r0, r1, r2
 | 
			
		||||
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	fadd.f r0, r1, r2
 | 
			
		||||
	fsub.f r0, r1, r2
 | 
			
		||||
	fmul.f r0, r1, r2
 | 
			
		||||
	fdiv.f r0, r1, r2
 | 
			
		||||
	fcmp.f r0, r1, r2
 | 
			
		||||
	fabs.f r0, r1, r2
 | 
			
		||||
	frsb.f r0, r1, r2
 | 
			
		||||
	fmax.f r0, r1, r2
 | 
			
		||||
	frcp.f r0, r1, r2
 | 
			
		||||
	frsqrt.f r0, r1, r2
 | 
			
		||||
	fnmul.f r0, r1, r2
 | 
			
		||||
	fmin.f r0, r1, r2
 | 
			
		||||
	fld1.f r0, r1, r2
 | 
			
		||||
	fld0.f r0, r1, r2
 | 
			
		||||
	log2.f r0, r1, r2
 | 
			
		||||
	exp2.f r0, r1, r2
 | 
			
		||||
	divs.f r0, r1, r2
 | 
			
		||||
	divu.f r0, r1, r2
 | 
			
		||||
	divs.f r0, r1, #31
 | 
			
		||||
	divu.f r0, r1, #31
 | 
			
		||||
	adds256.f r0, r1, r2
 | 
			
		||||
 | 
			
		||||
label:
 | 
			
		||||
	b label
 | 
			
		||||
	b forward
 | 
			
		||||
	b label
 | 
			
		||||
	b main
 | 
			
		||||
	b.f label
 | 
			
		||||
	b.f forward
 | 
			
		||||
	b.f main
 | 
			
		||||
	bl label
 | 
			
		||||
	bl forward
 | 
			
		||||
	bl main
 | 
			
		||||
forward:
 | 
			
		||||
 | 
			
		||||
	push r0
 | 
			
		||||
	push r0, lr
 | 
			
		||||
	push r0-r5
 | 
			
		||||
	push r0-r5, lr
 | 
			
		||||
	push r6
 | 
			
		||||
	push r16
 | 
			
		||||
	push r24
 | 
			
		||||
	push lr
 | 
			
		||||
 | 
			
		||||
	pop r0
 | 
			
		||||
	pop r0, pc
 | 
			
		||||
	pop r0-r5
 | 
			
		||||
	pop r0-r5, pc
 | 
			
		||||
	pop r6
 | 
			
		||||
	pop r16
 | 
			
		||||
	pop r24
 | 
			
		||||
	pop pc
 | 
			
		||||
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
    ld r0, (sp)
 | 
			
		||||
    st r0, (sp)
 | 
			
		||||
    ld r0, 4(sp)
 | 
			
		||||
    st r0, 4(sp)
 | 
			
		||||
    ld r0, -4(sp)
 | 
			
		||||
    st r0, -4(sp)
 | 
			
		||||
    ld r0, 5(sp)
 | 
			
		||||
    st r0, 5(sp)
 | 
			
		||||
    ld r0, -5(sp)
 | 
			
		||||
    st r0, -5(sp)
 | 
			
		||||
 | 
			
		||||
    ld r0, (r1)
 | 
			
		||||
    st r0, (r1)
 | 
			
		||||
    ld r16, (r1)
 | 
			
		||||
    st r16, (r1)
 | 
			
		||||
    ldh r0, (r1)
 | 
			
		||||
    sth r0, (r1)
 | 
			
		||||
    ldb r0, (r1)
 | 
			
		||||
    stb r0, (r1)
 | 
			
		||||
    ldhs r0, (r1)
 | 
			
		||||
    sths r0, (r1)
 | 
			
		||||
    ldh r16, (r1)
 | 
			
		||||
    sth r16, (r1)
 | 
			
		||||
    ldb r16, (r1)
 | 
			
		||||
    stb r16, (r1)
 | 
			
		||||
    ldhs r16, (r1)
 | 
			
		||||
    sths r16, (r1)
 | 
			
		||||
    ld r0, 0x3c (r1)
 | 
			
		||||
    st r0, 0x3c (r1)
 | 
			
		||||
    ld r0, 0xfff (r1)
 | 
			
		||||
    st r0, 0xfff (r1)
 | 
			
		||||
    ld r1, 0xffff (r0)
 | 
			
		||||
    st r1, 0xffff (r0)
 | 
			
		||||
    ld r0, -1 (r1)
 | 
			
		||||
    st r0, -1 (r1)
 | 
			
		||||
    ld r16, 0x3c (r1)
 | 
			
		||||
    st r16, 0x3c (r1)
 | 
			
		||||
    ld r16, 0xfff (r1)
 | 
			
		||||
    st r16, 0xfff (r1)
 | 
			
		||||
    ld r16, 0xffff (r0)
 | 
			
		||||
    st r16, 0xffff (r0)
 | 
			
		||||
    ld r16, -1 (r1)
 | 
			
		||||
    st r16, -1 (r1)
 | 
			
		||||
 | 
			
		||||
	ld.f r0, (r1)
 | 
			
		||||
	st.f r0, (r1)
 | 
			
		||||
	ld.f r0, 8 (r1)
 | 
			
		||||
	st.f r0, 8 (r1)
 | 
			
		||||
 | 
			
		||||
	ld r0, (r1, r2)
 | 
			
		||||
	st r0, (r1, r2)
 | 
			
		||||
	ld.f r0, (pc, pc)
 | 
			
		||||
	st.f r0, (pc, pc)
 | 
			
		||||
 | 
			
		||||
near:
 | 
			
		||||
	ld r0, (r1)++
 | 
			
		||||
	st r0, (r1)++
 | 
			
		||||
	ld.f pc, (pc)++
 | 
			
		||||
	st.f pc, (pc)++
 | 
			
		||||
 | 
			
		||||
	ld r0, near
 | 
			
		||||
	ld r0, main
 | 
			
		||||
	st r0, near
 | 
			
		||||
	st r0, main
 | 
			
		||||
	ldb r0, near
 | 
			
		||||
	ldb r0, main
 | 
			
		||||
	stb r0, near
 | 
			
		||||
	stb r0, main
 | 
			
		||||
 | 
			
		||||
	b.eq r0, r1, near
 | 
			
		||||
	b r0, r1, near
 | 
			
		||||
	addcmpb r0, r1, r2, .
 | 
			
		||||
	addcmpb r0, #1, r2, .
 | 
			
		||||
	addcmpb r0, r1, #1, .
 | 
			
		||||
	addcmpb r0, #1, #2, .
 | 
			
		||||
							
								
								
									
										13
									
								
								man/.distr
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								man/.distr
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,14 +1,8 @@
 | 
			
		|||
6500_as.6
 | 
			
		||||
6800_as.6
 | 
			
		||||
6805_as.6
 | 
			
		||||
6809_as.6
 | 
			
		||||
8080_as.6
 | 
			
		||||
z8000_as.6
 | 
			
		||||
i80_as.6
 | 
			
		||||
i86_as.6
 | 
			
		||||
i386_as.6
 | 
			
		||||
m68k2_as.6
 | 
			
		||||
ns_as.6
 | 
			
		||||
pdp_as.6
 | 
			
		||||
m68020_as.6
 | 
			
		||||
vc4_as.6
 | 
			
		||||
z80_as.6
 | 
			
		||||
em_cg.6
 | 
			
		||||
em_ncg.6
 | 
			
		||||
| 
						 | 
				
			
			@ -17,4 +11,3 @@ libpc.7
 | 
			
		|||
head
 | 
			
		||||
pc_prlib.7
 | 
			
		||||
uni_ass.6
 | 
			
		||||
proto.make
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										45
									
								
								man/vc4_as.6
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								man/vc4_as.6
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
.\" $Header$
 | 
			
		||||
.TH VC4_AS 1
 | 
			
		||||
.ad
 | 
			
		||||
.SH NAME
 | 
			
		||||
vc4_as \- assembler for Broadcom VideoCore IV
 | 
			
		||||
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
/usr/em/lib/vc4_as [options] argument ...
 | 
			
		||||
 | 
			
		||||
.SH DESCRIPTION
 | 
			
		||||
This assembler is made with the general framework
 | 
			
		||||
described in \fIuni_ass\fP(6).
 | 
			
		||||
 | 
			
		||||
.SH SYNTAX
 | 
			
		||||
The assembler uses a modified version of the syntax described in
 | 
			
		||||
https://github.com/hermanhermitage/videocoreiv/wiki/VideoCore-IV-Programmers-Manual:
 | 
			
		||||
condition codes must be prefixed with a full stop. Vector instructions are not
 | 
			
		||||
yet supported.
 | 
			
		||||
 | 
			
		||||
.SH "SEE ALSO"
 | 
			
		||||
uni_ass(6),
 | 
			
		||||
ack(1),
 | 
			
		||||
.br
 | 
			
		||||
https://github.com/hermanhermitage/videocoreiv
 | 
			
		||||
.SH EXAMPLE
 | 
			
		||||
.nf
 | 
			
		||||
.ta 8n 16n 24n 32n 40n 48n
 | 
			
		||||
An example of VideoCore IV assembly language:
 | 
			
		||||
 | 
			
		||||
        ldb r0, __uart_status
 | 
			
		||||
        b.eq r0, #0, 1b
 | 
			
		||||
 | 
			
		||||
        ! receive 1 byte (returned in r0)
 | 
			
		||||
        mov r1, #AUX_MU_LSR_REG
 | 
			
		||||
        mov r2, #AUX_MU_IO_REG
 | 
			
		||||
        ! loop until char available
 | 
			
		||||
recvwait:
 | 
			
		||||
        ld r3, (r1)
 | 
			
		||||
        and r3, #0x1
 | 
			
		||||
        b.ne r3, #0x1, recvwait
 | 
			
		||||
 | 
			
		||||
        ldb r0, (r2)
 | 
			
		||||
1:
 | 
			
		||||
        b lr
 | 
			
		||||
.fi
 | 
			
		||||
| 
						 | 
				
			
			@ -3,11 +3,19 @@
 | 
			
		|||
# $Revision$
 | 
			
		||||
 | 
			
		||||
var w=2
 | 
			
		||||
var wa=1
 | 
			
		||||
var p=2
 | 
			
		||||
var pa=1
 | 
			
		||||
var s=2
 | 
			
		||||
var sa=1
 | 
			
		||||
var l=4
 | 
			
		||||
var la=1
 | 
			
		||||
var f=4
 | 
			
		||||
var fa=1
 | 
			
		||||
var d=8
 | 
			
		||||
var da=1
 | 
			
		||||
var x=8
 | 
			
		||||
var xa=1
 | 
			
		||||
var ARCH=i80
 | 
			
		||||
var PLATFORM=cpm
 | 
			
		||||
var PLATFORMDIR={EM}/share/ack/{PLATFORM}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,11 +3,19 @@
 | 
			
		|||
# $Revision$
 | 
			
		||||
 | 
			
		||||
var w=4
 | 
			
		||||
var p=4
 | 
			
		||||
var wa=4
 | 
			
		||||
var p={w}
 | 
			
		||||
var pa={w}
 | 
			
		||||
var s=2
 | 
			
		||||
var l=4
 | 
			
		||||
var f=4
 | 
			
		||||
var sa={s}
 | 
			
		||||
var l={w}
 | 
			
		||||
var la={w}
 | 
			
		||||
var f={w}
 | 
			
		||||
var fa={w}
 | 
			
		||||
var d=8
 | 
			
		||||
var da={d}
 | 
			
		||||
var x=8
 | 
			
		||||
var xa={x}
 | 
			
		||||
var ARCH=i386
 | 
			
		||||
var PLATFORM=linux386
 | 
			
		||||
var PLATFORMDIR={EM}/share/ack/{PLATFORM}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,11 +3,19 @@
 | 
			
		|||
# $Revision: 1.1 $
 | 
			
		||||
 | 
			
		||||
var w=4
 | 
			
		||||
var p=4
 | 
			
		||||
var wa=4
 | 
			
		||||
var p={w}
 | 
			
		||||
var pa={w}
 | 
			
		||||
var s=2
 | 
			
		||||
var l=4
 | 
			
		||||
var f=4
 | 
			
		||||
var sa={s}
 | 
			
		||||
var l={w}
 | 
			
		||||
var la={w}
 | 
			
		||||
var f={w}
 | 
			
		||||
var fa={w}
 | 
			
		||||
var d=8
 | 
			
		||||
var da={d}
 | 
			
		||||
var x=8
 | 
			
		||||
var xa={x}
 | 
			
		||||
var ARCH=m68020
 | 
			
		||||
var PLATFORM=linux68k
 | 
			
		||||
var PLATFORMDIR={EM}/share/ack/{PLATFORM}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,11 +3,19 @@
 | 
			
		|||
# $Revision: 1.1 $
 | 
			
		||||
 | 
			
		||||
var w=4
 | 
			
		||||
var p=4
 | 
			
		||||
var wa=4
 | 
			
		||||
var p={w}
 | 
			
		||||
var pa={w}
 | 
			
		||||
var s=2
 | 
			
		||||
var l=4
 | 
			
		||||
var f=4
 | 
			
		||||
var sa={s}
 | 
			
		||||
var l={w}
 | 
			
		||||
var la={w}
 | 
			
		||||
var f={w}
 | 
			
		||||
var fa={w}
 | 
			
		||||
var d=8
 | 
			
		||||
var da={d}
 | 
			
		||||
var x=8
 | 
			
		||||
var xa={x}
 | 
			
		||||
var ARCH=powerpc
 | 
			
		||||
var PLATFORM=linuxppc
 | 
			
		||||
var PLATFORMDIR={EM}/share/ack/{PLATFORM}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,11 +3,19 @@
 | 
			
		|||
# $Revision$
 | 
			
		||||
 | 
			
		||||
var w=2
 | 
			
		||||
var wa=1
 | 
			
		||||
var p=2
 | 
			
		||||
var pa=1
 | 
			
		||||
var s=2
 | 
			
		||||
var sa=1
 | 
			
		||||
var l=4
 | 
			
		||||
var la=1
 | 
			
		||||
var f=4
 | 
			
		||||
var fa=1
 | 
			
		||||
var d=8
 | 
			
		||||
var da=1
 | 
			
		||||
var x=8
 | 
			
		||||
var xa=1
 | 
			
		||||
var ARCH=i86
 | 
			
		||||
var PLATFORM=pc86
 | 
			
		||||
var PLATFORMDIR={EM}/share/ack/{PLATFORM}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										31
									
								
								plat/rpi/.distr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								plat/rpi/.distr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
descr
 | 
			
		||||
boot.s
 | 
			
		||||
build.mk
 | 
			
		||||
README
 | 
			
		||||
include/ack/config.h
 | 
			
		||||
include/sys/select.h
 | 
			
		||||
include/unistd.h
 | 
			
		||||
include/pi.h
 | 
			
		||||
include/termios.h
 | 
			
		||||
libsys/brk.c
 | 
			
		||||
libsys/close.c
 | 
			
		||||
libsys/creat.c
 | 
			
		||||
libsys/errno.s
 | 
			
		||||
libsys/getpid.c
 | 
			
		||||
libsys/_hol0.s
 | 
			
		||||
libsys/isatty.c
 | 
			
		||||
libsys/kill.c
 | 
			
		||||
libsys/libsysasm.h
 | 
			
		||||
libsys/libsys.h
 | 
			
		||||
libsys/lseek.c
 | 
			
		||||
libsys/open.c
 | 
			
		||||
libsys/pi_phys_to_user.s
 | 
			
		||||
libsys/pi_uart.s
 | 
			
		||||
libsys/pi_user_to_phys.s
 | 
			
		||||
libsys/read.c
 | 
			
		||||
libsys/select.c
 | 
			
		||||
libsys/signal.c
 | 
			
		||||
libsys/tcgetattr.c
 | 
			
		||||
libsys/tcsetattr.c
 | 
			
		||||
libsys/time.c
 | 
			
		||||
libsys/write.c
 | 
			
		||||
							
								
								
									
										69
									
								
								plat/rpi/README
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								plat/rpi/README
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,69 @@
 | 
			
		|||
VideoCore IV support in the ACK
 | 
			
		||||
===============================
 | 
			
		||||
 | 
			
		||||
This is a fairly crude port of the ACK to produce VideoCore IV machine
 | 
			
		||||
code, suitable for use on the Raspberry Pi. It produces terrible but
 | 
			
		||||
working code. The resulting binaries can be used either bare metal or
 | 
			
		||||
loaded as a GPU kernel and executed using a modified mailbox.c (see below).
 | 
			
		||||
Currently floating point support is present but incomplete; and as the
 | 
			
		||||
VideoCore IV does not have double-precision float support, the C compiler
 | 
			
		||||
treats doubles as single precision.
 | 
			
		||||
 | 
			
		||||
As much of the standard C library as is relevant works; if
 | 
			
		||||
you're running in bare-metal mode, you can hook stdin/stdout up to the
 | 
			
		||||
mini UART. (Obviously, in kernel mode you can't.)
 | 
			
		||||
 | 
			
		||||
Important note! The malloc heap expects your program to be loaded into a
 | 
			
		||||
chunk of memory that's 128kB large. You must make sure that this is the case,
 | 
			
		||||
or Bad Stuff will happen.
 | 
			
		||||
 | 
			
		||||
Output binaries are fully PIC and can be loaded anywhere (this is one of the
 | 
			
		||||
things that makes the code so terrible). You must use the pi_user_to_phys()
 | 
			
		||||
and pi_phys_to_user() to translate pointers from physical to user and vice
 | 
			
		||||
versa. If you don't, Bad Stuff will happen.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Bare metal mode
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
To run a binary bare metal, compile it:
 | 
			
		||||
 | 
			
		||||
    ack -mrpi -O program.c -o bootcode.bin
 | 
			
		||||
 | 
			
		||||
...and copy the bootcode.bin file to the root of an SD card. Boot the Pi.
 | 
			
		||||
Your program will run.
 | 
			
		||||
 | 
			
		||||
To use the UART, #include <pi.h> and call pi_init_uart() at the top of your
 | 
			
		||||
program. This will set it up and connect it to stdin/stdout. It's 115200 8n1.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Kernel mode
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
This will require some hacking at your end.
 | 
			
		||||
 | 
			
		||||
Go here, and follow the instructions.
 | 
			
		||||
 | 
			
		||||
https://github.com/hermanhermitage/videocoreiv/wiki/VideoCore-IV-Kernels-under-Linux
 | 
			
		||||
 | 
			
		||||
Now compile your program:
 | 
			
		||||
 | 
			
		||||
    ack -mrpi -O program.c -o alpha.bin
 | 
			
		||||
 | 
			
		||||
MAKE SURE YOU AREN'T USING ANY MEMORY ALLOCATION. Copy the alpha.bin onto
 | 
			
		||||
the Pi, and run it with mailbox.c.
 | 
			
		||||
 | 
			
		||||
To get data in and out, #include <pi.h> and look at the pi_kernel_parameters
 | 
			
		||||
variable. It's a structure that is initialised with the data that's passed in
 | 
			
		||||
from mailbox.c (currently four pointers and two integers).
 | 
			
		||||
 | 
			
		||||
If you want to use malloc() and friends, you'll need to hack mailbox.c so
 | 
			
		||||
that the buffer containing the code is at least 128kB, or you're likely to
 | 
			
		||||
corrupt the VideoCore's workspace and crash it.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
David Given <dg@cowlark.com>
 | 
			
		||||
2013-06-06
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										120
									
								
								plat/rpi/boot.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								plat/rpi/boot.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,120 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
! Declare segments (the order is important).
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
 | 
			
		||||
#define gp r15
 | 
			
		||||
#define STACKSIZE 1*1024
 | 
			
		||||
 | 
			
		||||
! MAIN ENTRY POINT
 | 
			
		||||
 | 
			
		||||
begtext:
 | 
			
		||||
	! This empty space is required by the boot loader.
 | 
			
		||||
 | 
			
		||||
kernel_start:
 | 
			
		||||
	! When running as a kernel, we need to preserve all registers. We save
 | 
			
		||||
	! them onto the default stack.
 | 
			
		||||
	push r0-r24
 | 
			
		||||
	b baremetal_start
 | 
			
		||||
	.space 506 ! first 512 bytes are ignored by the boot loader
 | 
			
		||||
baremetal_start:
 | 
			
		||||
	! Wipe the bss (including the new stack).
 | 
			
		||||
 | 
			
		||||
	lea r6, begbss
 | 
			
		||||
	lea r7, endbss
 | 
			
		||||
	mov r8, #0
 | 
			
		||||
_1:
 | 
			
		||||
	stb r8, (r6)
 | 
			
		||||
	addcmpb.lt r6, #1, r7, _1
 | 
			
		||||
 | 
			
		||||
	! Save system registers.
 | 
			
		||||
 | 
			
		||||
	st fp, .returnfp
 | 
			
		||||
	st sp, .returnsp
 | 
			
		||||
	st lr, .returnlr
 | 
			
		||||
 | 
			
		||||
	lea gp, begtext
 | 
			
		||||
	lea sp, .stack + STACKSIZE
 | 
			
		||||
 | 
			
		||||
	! Save the kernel parameters.
 | 
			
		||||
 | 
			
		||||
	sub r0, gp ! fix up pointer
 | 
			
		||||
	sub r1, gp ! fix up pointer
 | 
			
		||||
	sub r2, gp ! fix up pointer
 | 
			
		||||
	sub r3, gp ! fix up pointer
 | 
			
		||||
	push r0-r5
 | 
			
		||||
	sub r0, sp, gp
 | 
			
		||||
	st r0, _pi_kernel_parameters
 | 
			
		||||
 | 
			
		||||
	! Push standard parameters onto the stack and go.
 | 
			
		||||
	
 | 
			
		||||
	mov r0, #0
 | 
			
		||||
	push r0                 ! envp
 | 
			
		||||
	push r0                 ! argv
 | 
			
		||||
	push r0                 ! argc
 | 
			
		||||
 | 
			
		||||
	! Call the language startup code.
 | 
			
		||||
 | 
			
		||||
	bl __m_a_i_n
 | 
			
		||||
 | 
			
		||||
	! Fall through to __exit if this returns.
 | 
			
		||||
 | 
			
		||||
.define __exit
 | 
			
		||||
__exit:
 | 
			
		||||
	! It only makes sense to get here if we're in kernel mode. If we're in
 | 
			
		||||
	! bare-metal mode, we'll just crash, but that's fine.
 | 
			
		||||
 | 
			
		||||
	st r0, _pi_kernel_parameters ! save return value
 | 
			
		||||
	mov r0, sr
 | 
			
		||||
	ld fp, .returnfp
 | 
			
		||||
	ld sp, .returnsp
 | 
			
		||||
	ld lr, .returnlr
 | 
			
		||||
	pop r0-r24
 | 
			
		||||
	ld r0, _pi_kernel_parameters ! restore return value
 | 
			
		||||
	b lr
 | 
			
		||||
 | 
			
		||||
! Define symbols at the beginning of our various segments, so that we can find
 | 
			
		||||
! them. (Except .text, which has already been done.)
 | 
			
		||||
 | 
			
		||||
.define begtext, begdata, begbss
 | 
			
		||||
.sect .data;       begdata:
 | 
			
		||||
.sect .rom;        begrom:
 | 
			
		||||
.sect .bss;        begbss:
 | 
			
		||||
 | 
			
		||||
! Some magic data. All EM systems need these.
 | 
			
		||||
 | 
			
		||||
.define .trppc, .ignmask, _errno
 | 
			
		||||
.comm .trppc, 4
 | 
			
		||||
.comm .ignmask, 4
 | 
			
		||||
.comm _errno, 4
 | 
			
		||||
 | 
			
		||||
! We store the stack pointer and return address on entry so that we can
 | 
			
		||||
! cleanly exit.
 | 
			
		||||
 | 
			
		||||
.comm .returnfp, 4
 | 
			
		||||
.comm .returnsp, 4
 | 
			
		||||
.comm .returnlr, 4
 | 
			
		||||
 | 
			
		||||
.define _pi_kernel_parameters
 | 
			
		||||
.comm _pi_kernel_parameters, 4
 | 
			
		||||
 | 
			
		||||
.define .linenumber, .filename
 | 
			
		||||
.comm .linenumber, 4         ! current linenumber (used for debugging)
 | 
			
		||||
.comm .filename, 4           ! ptr to current filename (used for debugging)
 | 
			
		||||
 | 
			
		||||
! User stack.
 | 
			
		||||
 | 
			
		||||
.comm .stack, STACKSIZE
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										52
									
								
								plat/rpi/build.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								plat/rpi/build.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
# Build script for Raspberry Pi bare-metal executables (using the
 | 
			
		||||
# VideoCore IV processor, not the ARM).
 | 
			
		||||
#
 | 
			
		||||
# © 2013 David Given
 | 
			
		||||
# This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
# See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 | 
			
		||||
ARCH := vc4
 | 
			
		||||
PLATFORM := rpi
 | 
			
		||||
OPTIMISATION := -O
 | 
			
		||||
 | 
			
		||||
D := plat/rpi/
 | 
			
		||||
 | 
			
		||||
platform-headers := \
 | 
			
		||||
	unistd.h \
 | 
			
		||||
	termios.h \
 | 
			
		||||
	pi.h \
 | 
			
		||||
	ack/config.h
 | 
			
		||||
 | 
			
		||||
platform-libsys := \
 | 
			
		||||
	_hol0.s \
 | 
			
		||||
	errno.s \
 | 
			
		||||
	pi_phys_to_user.s \
 | 
			
		||||
	pi_user_to_phys.s \
 | 
			
		||||
	pi_uart.s \
 | 
			
		||||
	pi_fast_mode.s \
 | 
			
		||||
	creat.c \
 | 
			
		||||
	close.c \
 | 
			
		||||
	open.c \
 | 
			
		||||
	read.c \
 | 
			
		||||
	write.c \
 | 
			
		||||
	isatty.c \
 | 
			
		||||
	brk.c \
 | 
			
		||||
	getpid.c \
 | 
			
		||||
	kill.c \
 | 
			
		||||
	lseek.c \
 | 
			
		||||
	time.c \
 | 
			
		||||
	signal.c \
 | 
			
		||||
	tcgetattr.c \
 | 
			
		||||
	tcsetattr.c \
 | 
			
		||||
	select.c
 | 
			
		||||
 | 
			
		||||
$(eval $(call build-platform))
 | 
			
		||||
 | 
			
		||||
define build-rpi-boot-impl
 | 
			
		||||
	$(call reset)
 | 
			
		||||
	$(call ackfile, $D/boot.s)
 | 
			
		||||
	$(call installto, $(PLATIND)/$(PLATFORM)/boot.o)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(build-rpi-boot-impl))
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										77
									
								
								plat/rpi/descr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								plat/rpi/descr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,77 @@
 | 
			
		|||
# $Source$
 | 
			
		||||
# $State$
 | 
			
		||||
# $Revision$
 | 
			
		||||
 | 
			
		||||
var w=4
 | 
			
		||||
var wa=4
 | 
			
		||||
var p={w}
 | 
			
		||||
var pa={w}
 | 
			
		||||
var s=2
 | 
			
		||||
var sa={s}
 | 
			
		||||
var l={w}
 | 
			
		||||
var la={w}
 | 
			
		||||
var f={w}
 | 
			
		||||
var fa={w}
 | 
			
		||||
var d={w}
 | 
			
		||||
var da={w}
 | 
			
		||||
var x={w}
 | 
			
		||||
var xa={w}
 | 
			
		||||
var ARCH=vc4
 | 
			
		||||
var PLATFORM=rpi
 | 
			
		||||
var PLATFORMDIR={EM}/share/ack/{PLATFORM}
 | 
			
		||||
var CPP_F=-D__unix
 | 
			
		||||
var ALIGN=-a0:2 -a1:4 -a2:4 -a3:4
 | 
			
		||||
var MACHOPT_F=-m8
 | 
			
		||||
 | 
			
		||||
# Override the setting in fe so that files compiled for this platform can see
 | 
			
		||||
# the platform-specific headers.
 | 
			
		||||
 | 
			
		||||
var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/share/ack/include/ansi
 | 
			
		||||
 | 
			
		||||
name be
 | 
			
		||||
	from .m.g
 | 
			
		||||
	to .s
 | 
			
		||||
	program {EM}/lib/ack/{PLATFORM}/ncg
 | 
			
		||||
	args <
 | 
			
		||||
	stdout
 | 
			
		||||
	need .e
 | 
			
		||||
end
 | 
			
		||||
name as
 | 
			
		||||
	from .s.so
 | 
			
		||||
	to .o
 | 
			
		||||
	program {EM}/lib/ack/{PLATFORM}/as
 | 
			
		||||
	args - -o > <
 | 
			
		||||
	prep cond
 | 
			
		||||
end
 | 
			
		||||
name led
 | 
			
		||||
	from .o.a
 | 
			
		||||
	to .out
 | 
			
		||||
	program {EM}/lib/ack/em_led
 | 
			
		||||
	mapflag -l* LNAME={PLATFORMDIR}/lib*
 | 
			
		||||
	mapflag -i SEPID=-b1:0
 | 
			
		||||
	mapflag -fp FLOATS={EM}/{ILIB}fp
 | 
			
		||||
	args {ALIGN} {SEPID?} \
 | 
			
		||||
	    (.e:{HEAD}={PLATFORMDIR}/boot.o) \
 | 
			
		||||
		({RTS}:.ocm.b={PLATFORMDIR}/c-ansi.o) \
 | 
			
		||||
		({RTS}:.c={PLATFORMDIR}/c-ansi.o) \
 | 
			
		||||
		({RTS}:.mod={PLATFORMDIR}/modula2.o) \
 | 
			
		||||
		({RTS}:.p={PLATFORMDIR}/pascal.o) \
 | 
			
		||||
		-o > < \
 | 
			
		||||
		(.p:{TAIL}={PLATFORMDIR}/libpascal.a) \
 | 
			
		||||
		(.b:{TAIL}={PLATFORMDIR}/libbasic.a) \
 | 
			
		||||
		(.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \
 | 
			
		||||
		(.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \
 | 
			
		||||
		(.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \
 | 
			
		||||
		{FLOATS?} \
 | 
			
		||||
		(.e:{TAIL}={PLATFORMDIR}/libem.a \
 | 
			
		||||
		           {PLATFORMDIR}/libsys.a \
 | 
			
		||||
		           {PLATFORMDIR}/libend.a)
 | 
			
		||||
	linker
 | 
			
		||||
end
 | 
			
		||||
name cv
 | 
			
		||||
	from .out
 | 
			
		||||
	to .img
 | 
			
		||||
	program {EM}/bin/aslod
 | 
			
		||||
	args < >
 | 
			
		||||
	outfile raspberrypi.bin
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										11
									
								
								plat/rpi/include/ack/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								plat/rpi/include/ack/config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _ACK_CONFIG_H
 | 
			
		||||
#define _ACK_CONFIG_H
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										48
									
								
								plat/rpi/include/pi.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								plat/rpi/include/pi.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef PI_H
 | 
			
		||||
#define PI_H
 | 
			
		||||
 | 
			
		||||
/* When running in kernel mode, this structure gets the incoming parameters.
 | 
			
		||||
 * In bare metal mode, it's gibberish. */
 | 
			
		||||
 | 
			
		||||
struct pi_kernel_parameters
 | 
			
		||||
{
 | 
			
		||||
	int r5;
 | 
			
		||||
	int r4;
 | 
			
		||||
	void* r3;
 | 
			
		||||
	void* r2;
 | 
			
		||||
	void* r1;
 | 
			
		||||
	void* r0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern struct pi_kernel_parameters* pi_kernel_parameters;
 | 
			
		||||
 | 
			
		||||
/* Initialise the mini UART (only do this if running on bare metal! */
 | 
			
		||||
extern void pi_init_uart(void);
 | 
			
		||||
 | 
			
		||||
/* Converts a pointer from a physical address to a user address. */
 | 
			
		||||
extern void* pi_phys_to_user(void* ptr);
 | 
			
		||||
 | 
			
		||||
/* Converts a pointer from a user address to a physical address. */
 | 
			
		||||
extern void* pi_user_to_phys(void* ptr);
 | 
			
		||||
 | 
			
		||||
/* Change the clock speed from 19.2MHz to 250MHz. Must be called *before*
 | 
			
		||||
 * pi_init_uart(). */
 | 
			
		||||
extern void pi_fast_mode(void);
 | 
			
		||||
 | 
			
		||||
/* Initialise the RAM. */
 | 
			
		||||
extern void pi_init_ram(void);
 | 
			
		||||
 | 
			
		||||
/* The current clock speed (used by pi_init_uart to calculate the correct
 | 
			
		||||
 * UART settings). */
 | 
			
		||||
 | 
			
		||||
extern int pi_clock_speed;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								plat/rpi/include/sys/select.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								plat/rpi/include/sys/select.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _SYS_SELECT_H
 | 
			
		||||
#define _SYS_SELECT_H
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										47
									
								
								plat/rpi/include/termios.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								plat/rpi/include/termios.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,47 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _TERMIOS_H
 | 
			
		||||
#define _TERMIOS_H
 | 
			
		||||
 | 
			
		||||
typedef unsigned char tcflag_t;
 | 
			
		||||
 | 
			
		||||
struct termios
 | 
			
		||||
{
 | 
			
		||||
    tcflag_t c_iflag;
 | 
			
		||||
    tcflag_t c_oflag;
 | 
			
		||||
    tcflag_t c_lflag;
 | 
			
		||||
    tcflag_t c_cflag;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define ONLCR 1
 | 
			
		||||
#define ECHO 2
 | 
			
		||||
#define INLCR 4
 | 
			
		||||
 | 
			
		||||
/* Dummied parameters for compatibility --- only the ones above are
 | 
			
		||||
 * honoured. */
 | 
			
		||||
 | 
			
		||||
#define BRKINT 0
 | 
			
		||||
#define ICRNL 0
 | 
			
		||||
#define INPCK 0
 | 
			
		||||
#define ISTRIP 0
 | 
			
		||||
#define IXON 0
 | 
			
		||||
#define CS8 0
 | 
			
		||||
#define ICANON 0
 | 
			
		||||
#define IEXTEN 0
 | 
			
		||||
#define ISIG 0
 | 
			
		||||
 | 
			
		||||
#define OPOST ONLCR
 | 
			
		||||
 | 
			
		||||
#define TCSANOW 0
 | 
			
		||||
#define TCSADRAIN 1
 | 
			
		||||
#define TCSAFLUSH 2
 | 
			
		||||
 | 
			
		||||
extern int tcgetattr(int fd, struct termios* t);
 | 
			
		||||
extern int tcsetattr(int fd, int actions, struct termios* t);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										105
									
								
								plat/rpi/include/unistd.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								plat/rpi/include/unistd.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,105 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _UNISTD_H
 | 
			
		||||
#define _UNISTD_H
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
/* Types */
 | 
			
		||||
 | 
			
		||||
typedef int pid_t;
 | 
			
		||||
typedef int mode_t;
 | 
			
		||||
 | 
			
		||||
typedef long suseconds_t;
 | 
			
		||||
 | 
			
		||||
/* Time handling. */
 | 
			
		||||
 | 
			
		||||
struct timeval
 | 
			
		||||
{
 | 
			
		||||
	time_t tv_sec;
 | 
			
		||||
	suseconds_t tv_usec;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct timezone
 | 
			
		||||
{
 | 
			
		||||
	int tz_minuteswest;
 | 
			
		||||
	int tz_dsttime;
 | 
			
		||||
}; /* obsolete, unused */
 | 
			
		||||
 | 
			
		||||
extern int gettimeofday(struct timeval* tv, struct timezone* tz);
 | 
			
		||||
extern int settimeofday(const struct timeval* tv, const struct timezone* tz);
 | 
			
		||||
 | 
			
		||||
/* Constants for file access (open and friends) */
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	O_ACCMODE = 0x3,
 | 
			
		||||
	
 | 
			
		||||
	O_RDONLY = 0,
 | 
			
		||||
	O_WRONLY = 1,
 | 
			
		||||
	O_RDWR = 2,
 | 
			
		||||
	
 | 
			
		||||
	O_CREAT = 0100,
 | 
			
		||||
	O_TRUNC = 01000,
 | 
			
		||||
	O_APPEND = 02000,
 | 
			
		||||
	O_NONBLOCK = 04000
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Special variables */
 | 
			
		||||
 | 
			
		||||
extern char** environ;
 | 
			
		||||
 | 
			
		||||
/* Implemented system calls */
 | 
			
		||||
 | 
			
		||||
extern void _exit(int);
 | 
			
		||||
extern pid_t getpid(void);
 | 
			
		||||
extern void* sbrk(intptr_t increment);
 | 
			
		||||
extern int isatty(int d);
 | 
			
		||||
extern off_t lseek(int fildes, off_t offset, int whence);
 | 
			
		||||
extern int close(int d);
 | 
			
		||||
extern int open(const char* path, int access, ...);
 | 
			
		||||
extern int creat(const char* path, mode_t mode);
 | 
			
		||||
extern int read(int fd, void* buffer, size_t count);
 | 
			
		||||
extern int write(int fd, void* buffer, size_t count);
 | 
			
		||||
 | 
			
		||||
/* Unimplemented system calls (these are just prototypes to let the library
 | 
			
		||||
 * compile). */
 | 
			
		||||
 | 
			
		||||
extern int fcntl(int fd, int op, ...);
 | 
			
		||||
 | 
			
		||||
/* Signal handling */
 | 
			
		||||
 | 
			
		||||
typedef int sig_atomic_t;
 | 
			
		||||
 | 
			
		||||
#define SIG_ERR ((sighandler_t) -1)           /* Error return.  */
 | 
			
		||||
#define SIG_DFL ((sighandler_t) 0)            /* Default action.  */
 | 
			
		||||
#define SIG_IGN ((sighandler_t) 1)            /* Ignore signal.  */
 | 
			
		||||
 | 
			
		||||
#define SIGABRT         6       /* Abort (ANSI) */
 | 
			
		||||
#define SIGILL          11      /* Illegal instruction */
 | 
			
		||||
 | 
			
		||||
#define _NSIG           32      /* Biggest signal number + 1
 | 
			
		||||
                                   (not including real-time signals).  */
 | 
			
		||||
typedef void (*sighandler_t)(int);
 | 
			
		||||
extern sighandler_t signal(int signum, sighandler_t handler);
 | 
			
		||||
extern int raise(int signum);
 | 
			
		||||
 | 
			
		||||
/* Select */
 | 
			
		||||
 | 
			
		||||
typedef uint32_t fd_set;
 | 
			
		||||
 | 
			
		||||
extern int select(int nfds, fd_set *readfds, fd_set *writefds,
 | 
			
		||||
                  fd_set *exceptfds, struct timeval *timeout);
 | 
			
		||||
 | 
			
		||||
#define FD_ZERO(set) do { *set = 0; } while (0)
 | 
			
		||||
#define FD_SET(fd, set) do { *set |= (1<<fd); } while (0);
 | 
			
		||||
#define FD_CLR(fd, set) do { *set &= ~(1<<fd); } while (0);
 | 
			
		||||
#define FD_ISSET(fd, set) (*set | (1<<fd))
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										22
									
								
								plat/rpi/libsys/_hol0.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								plat/rpi/libsys/_hol0.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
! Declare segments (the order is important).
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
 | 
			
		||||
.sect .bss
 | 
			
		||||
 | 
			
		||||
! This data block is used to store information about the current line number
 | 
			
		||||
! and file.
 | 
			
		||||
 | 
			
		||||
.define hol0
 | 
			
		||||
.comm hol0, 8
 | 
			
		||||
							
								
								
									
										45
									
								
								plat/rpi/libsys/brk.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								plat/rpi/libsys/brk.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <pi.h>
 | 
			
		||||
 | 
			
		||||
#define	OUT_OF_MEMORY (void*)(-1)	/* sbrk returns this on failure */
 | 
			
		||||
#define STACK_BUFFER 1024 /* number of bytes to leave for stack */
 | 
			
		||||
 | 
			
		||||
extern char _end[1];
 | 
			
		||||
static char* current = _end;
 | 
			
		||||
 | 
			
		||||
/* Top of heap: we assume that the block of memory the binary is loaded in
 | 
			
		||||
 * is 256kB long. Because user pointers are always relative to the beginning
 | 
			
		||||
 * of the block, this makes the end address easy to calculate. */
 | 
			
		||||
static char* max = (char*) (128*1024);
 | 
			
		||||
 | 
			
		||||
int brk(void* newend)
 | 
			
		||||
{
 | 
			
		||||
	if ((newend >= (void*)max) || (newend < (void*)_end))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	current = newend;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void* sbrk(intptr_t increment)
 | 
			
		||||
{
 | 
			
		||||
	char* old;
 | 
			
		||||
	
 | 
			
		||||
	if (increment == 0)
 | 
			
		||||
		return current;
 | 
			
		||||
		
 | 
			
		||||
	old = current;
 | 
			
		||||
	if (brk(old + increment) < 0)
 | 
			
		||||
		return OUT_OF_MEMORY;
 | 
			
		||||
		
 | 
			
		||||
	return old;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								plat/rpi/libsys/close.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								plat/rpi/libsys/close.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
int close(int fd)
 | 
			
		||||
{
 | 
			
		||||
	errno = EBADF;
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								plat/rpi/libsys/creat.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								plat/rpi/libsys/creat.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include "libsys.h"
 | 
			
		||||
 | 
			
		||||
int open(const char* path, int access, ...)
 | 
			
		||||
{
 | 
			
		||||
	errno = EACCES;
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								plat/rpi/libsys/errno.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								plat/rpi/libsys/errno.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
! Declare segments (the order is important).
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
 | 
			
		||||
#define D(e) .define e; e
 | 
			
		||||
 | 
			
		||||
.sect .data
 | 
			
		||||
 | 
			
		||||
! Define various ACK error numbers. Note that these are *not* ANSI C
 | 
			
		||||
! errnos, and are used for different purposes.
 | 
			
		||||
 | 
			
		||||
D(ERANGE)         = 1
 | 
			
		||||
D(ESET)           = 2
 | 
			
		||||
D(EIDIVZ)         = 6
 | 
			
		||||
D(EHEAP)          = 17
 | 
			
		||||
D(EILLINS)        = 18
 | 
			
		||||
D(EODDZ)          = 19
 | 
			
		||||
D(ECASE)          = 20
 | 
			
		||||
D(EBADMON)        = 25
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								plat/rpi/libsys/getpid.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								plat/rpi/libsys/getpid.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
pid_t getpid(void)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								plat/rpi/libsys/isatty.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								plat/rpi/libsys/isatty.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
int isatty(int fd)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								plat/rpi/libsys/kill.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								plat/rpi/libsys/kill.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
int kill(pid_t pid, int sig)
 | 
			
		||||
{
 | 
			
		||||
	errno = EINVAL;
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								plat/rpi/libsys/libsys.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								plat/rpi/libsys/libsys.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef LIBSYS_H
 | 
			
		||||
#define LIBSYS_H
 | 
			
		||||
 | 
			
		||||
extern void _sys_rawwrite(unsigned char b);
 | 
			
		||||
extern unsigned char _sys_rawread(void);
 | 
			
		||||
extern int _sys_rawpoll(void);
 | 
			
		||||
 | 
			
		||||
extern void _sys_write_tty(char c);
 | 
			
		||||
 | 
			
		||||
extern int _sys_ttyflags;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										20
									
								
								plat/rpi/libsys/libsysasm.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								plat/rpi/libsys/libsysasm.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef LIBSYSASM_H
 | 
			
		||||
#define LIBSYSASM_H
 | 
			
		||||
 | 
			
		||||
! Declare segments (the order is important).
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
.sect .rom
 | 
			
		||||
.sect .data
 | 
			
		||||
.sect .bss
 | 
			
		||||
 | 
			
		||||
#define gp r15
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										16
									
								
								plat/rpi/libsys/lseek.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								plat/rpi/libsys/lseek.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
off_t lseek(int fd, off_t offset, int whence)
 | 
			
		||||
{
 | 
			
		||||
	errno = EINVAL;
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								plat/rpi/libsys/open.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								plat/rpi/libsys/open.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include "libsys.h"
 | 
			
		||||
 | 
			
		||||
int creat(const char* path, int mode)
 | 
			
		||||
{
 | 
			
		||||
	return open(path, O_CREAT|O_WRONLY|O_TRUNC, mode);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								plat/rpi/libsys/pi_fast_mode.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								plat/rpi/libsys/pi_fast_mode.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "libsysasm.h"
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
 | 
			
		||||
#define PASSWD 0x5a000000
 | 
			
		||||
#define PLLC 5
 | 
			
		||||
#define OSC 1
 | 
			
		||||
 | 
			
		||||
#define A2W                 0x7e102000
 | 
			
		||||
#define A2W_PLLC_MULT       0x7e102020
 | 
			
		||||
#define A2W_PLLC_MULT2      0x7e102120
 | 
			
		||||
#define A2W_PLLC_MULT_FRACT 0x7e102220
 | 
			
		||||
#define A2W_PLLx_DIV        0x7e102620
 | 
			
		||||
 | 
			
		||||
#define CM                  0x7e101000
 | 
			
		||||
#define CM_VPU_CTL          0x7e101008
 | 
			
		||||
#define CM_VPU_DIV          0x7e10100c
 | 
			
		||||
#define CM_TIME_DIV         0x7e1010ec
 | 
			
		||||
#define CM_TIME_CTL         0x7e1010e8
 | 
			
		||||
 | 
			
		||||
#define hash #
 | 
			
		||||
#define copy(A) A
 | 
			
		||||
#define poke(A, V) \
 | 
			
		||||
	mov r0, copy(hash) V; mov r1, copy(hash) A; st r0, (r1)
 | 
			
		||||
 | 
			
		||||
! Changes the clock speed to 250MHz.
 | 
			
		||||
 | 
			
		||||
.define _pi_fast_mode
 | 
			
		||||
_pi_fast_mode:
 | 
			
		||||
	poke(A2W + 0x190, 0x5a000001)
 | 
			
		||||
	poke(A2W_PLLC_MULT_FRACT, PASSWD | 87380)
 | 
			
		||||
	poke(A2W_PLLC_MULT2, PASSWD | 52 | 0x1000)
 | 
			
		||||
	poke(A2W + 0x3c, 0x5a000100)
 | 
			
		||||
	poke(A2W + 0x38, 0x5a000000)
 | 
			
		||||
	poke(A2W + 0x34, 0x5a144000)
 | 
			
		||||
	poke(A2W + 0x30, 0x5a000000)
 | 
			
		||||
	poke(CM + 0x108, 0x5a000200)
 | 
			
		||||
	poke(CM + 0x108, 0x5a0002aa)
 | 
			
		||||
	poke(A2W + 0x2c, 0x5a000000)
 | 
			
		||||
	poke(A2W + 0x28, 0x5a400000)
 | 
			
		||||
	poke(A2W + 0x24, 0x5a000005)
 | 
			
		||||
	poke(A2W_PLLC_MULT, PASSWD | 52 | 0x555000)
 | 
			
		||||
	poke(A2W_PLLC_MULT2, PASSWD | 52 | 0x21000)
 | 
			
		||||
	poke(A2W + 0x2c, 0x5a000042)
 | 
			
		||||
	poke(A2W + 0x28, 0x5a500401)
 | 
			
		||||
	poke(A2W + 0x24, 0x5a004005)
 | 
			
		||||
	poke(A2W_PLLC_MULT, PASSWD | 52 | 0x555000)
 | 
			
		||||
	poke(A2W_PLLx_DIV, PASSWD | 2)
 | 
			
		||||
	poke(CM + 0x108, 0x5a0002ab)
 | 
			
		||||
	poke(CM + 0x108, 0x5a0002aa)
 | 
			
		||||
	poke(CM + 0x108, 0x5a0002a8)
 | 
			
		||||
	poke(CM_VPU_CTL, PASSWD | 0x200 | OSC | 0x40)
 | 
			
		||||
	poke(CM_VPU_DIV, PASSWD | [4 << 12])
 | 
			
		||||
	poke(CM_VPU_CTL, PASSWD | PLLC | 0x40)
 | 
			
		||||
	poke(CM_VPU_CTL, PASSWD | PLLC | 0x50)
 | 
			
		||||
	poke(CM_TIME_DIV, PASSWD | [19 << 12] | 819)
 | 
			
		||||
	poke(CM_TIME_CTL, PASSWD | OSC | 0x10)
 | 
			
		||||
 | 
			
		||||
	mov r0, #250000000
 | 
			
		||||
	st r0, _pi_clock_speed
 | 
			
		||||
	b lr
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								plat/rpi/libsys/pi_phys_to_user.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								plat/rpi/libsys/pi_phys_to_user.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "libsysasm.h"
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
 | 
			
		||||
! Transforms a physical address into a user address.
 | 
			
		||||
 | 
			
		||||
.define _pi_phys_to_user
 | 
			
		||||
_pi_phys_to_user:
 | 
			
		||||
	ld r0, 0 (sp)
 | 
			
		||||
	sub r0, gp
 | 
			
		||||
	b lr
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										185
									
								
								plat/rpi/libsys/pi_uart.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								plat/rpi/libsys/pi_uart.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,185 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "libsysasm.h"
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
 | 
			
		||||
! Because of the low system clock rate, this baud rate might be inaccurate
 | 
			
		||||
! So be careful with your serial/terminal, some adjustment may be necessary.
 | 
			
		||||
TARGET_BAUD_RATE = 115200
 | 
			
		||||
 | 
			
		||||
GPFSEL1 = 0x7e200004
 | 
			
		||||
GPSET0 = 0x7e20001C
 | 
			
		||||
GPCLR0 = 0x7e200028
 | 
			
		||||
GPPUD = 0x7e200094
 | 
			
		||||
GPPUDCLK0 = 0x7e200098
 | 
			
		||||
 | 
			
		||||
AUX_ENABLES = 0x7e215004
 | 
			
		||||
AUX_MU_IO_REG = 0x7e215040
 | 
			
		||||
AUX_MU_IER_REG = 0x7e215044
 | 
			
		||||
AUX_MU_IIR_REG = 0x7e215048
 | 
			
		||||
AUX_MU_LCR_REG = 0x7e21504C
 | 
			
		||||
AUX_MU_MCR_REG = 0x7e215050
 | 
			
		||||
AUX_MU_LSR_REG = 0x7e215054
 | 
			
		||||
AUX_MU_MSR_REG = 0x7e215058
 | 
			
		||||
AUX_MU_SCRATCH = 0x7e21505C
 | 
			
		||||
AUX_MU_CNTL_REG = 0x7e215060
 | 
			
		||||
AUX_MU_STAT_REG = 0x7e215064
 | 
			
		||||
AUX_MU_BAUD_REG = 0x7e215068
 | 
			
		||||
 | 
			
		||||
! Sets up the mini UART for use as a console.
 | 
			
		||||
 | 
			
		||||
.define _pi_init_uart
 | 
			
		||||
_pi_init_uart:
 | 
			
		||||
	! Configure TX and RX GPIO pins for Mini Uart function.
 | 
			
		||||
	mov	r1, #GPFSEL1
 | 
			
		||||
	ld	r0, (r1)
 | 
			
		||||
	and	r0, #~[7<<12]
 | 
			
		||||
	or	r0, #2<<12
 | 
			
		||||
	and	r0, #~[7<<15]
 | 
			
		||||
	or	r0, #2<<15
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #GPPUD
 | 
			
		||||
	mov	r0, #0
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
delay1:
 | 
			
		||||
	add	r0, #1
 | 
			
		||||
	cmp	r0, #150
 | 
			
		||||
	b.ne delay1
 | 
			
		||||
 | 
			
		||||
	mov	r1, #GPPUDCLK0
 | 
			
		||||
	mov	r0, #[1<<14]|[1<<15]
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r0, #0
 | 
			
		||||
delay2:
 | 
			
		||||
	add	r0, #1
 | 
			
		||||
	cmp	r0, #150
 | 
			
		||||
	b.ne delay2
 | 
			
		||||
 | 
			
		||||
	mov	r1, #GPPUDCLK0
 | 
			
		||||
	mov	r0, #0
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	! Set up serial port
 | 
			
		||||
	mov	r1, #AUX_ENABLES
 | 
			
		||||
	mov	r0, #1
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_IER_REG
 | 
			
		||||
	mov	r0, #0
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_CNTL_REG
 | 
			
		||||
	mov	r0, #0
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_LCR_REG
 | 
			
		||||
	mov	r0, #3
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_MCR_REG
 | 
			
		||||
	mov	r0, #0
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_IER_REG
 | 
			
		||||
	mov	r0, #0
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_IIR_REG
 | 
			
		||||
	mov	r0, #0xC6
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_BAUD_REG
 | 
			
		||||
	ld r0, _pi_clock_speed
 | 
			
		||||
	mov r2, #TARGET_BAUD_RATE*8
 | 
			
		||||
	divu r0, r0, r2
 | 
			
		||||
	sub r0, #1
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_LCR_REG
 | 
			
		||||
	mov	r0, #3
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_CNTL_REG
 | 
			
		||||
	mov	r0, #3
 | 
			
		||||
	st	r0, (r1)
 | 
			
		||||
 | 
			
		||||
	! Mark the uart as being initialised.
 | 
			
		||||
	mov r0, #1
 | 
			
		||||
	stb r0, __uart_status
 | 
			
		||||
 | 
			
		||||
	b lr
 | 
			
		||||
 | 
			
		||||
! Send a single byte.
 | 
			
		||||
 | 
			
		||||
.define __sys_rawwrite
 | 
			
		||||
__sys_rawwrite:
 | 
			
		||||
	ldb r0, __uart_status
 | 
			
		||||
	b.eq r0, #0, 1f
 | 
			
		||||
 | 
			
		||||
	ld r0, (sp)
 | 
			
		||||
	mov r1, #AUX_MU_LSR_REG
 | 
			
		||||
	! loop until space available in Tx buffer
 | 
			
		||||
sendwait:
 | 
			
		||||
	ld	r2, (r1)
 | 
			
		||||
	and	r2, #0x20
 | 
			
		||||
	cmp	r2, #0x20
 | 
			
		||||
	b.ne sendwait
 | 
			
		||||
 | 
			
		||||
	mov	r1, #AUX_MU_IO_REG
 | 
			
		||||
	stb	r0, (r1)
 | 
			
		||||
 | 
			
		||||
1:
 | 
			
		||||
	b lr
 | 
			
		||||
 | 
			
		||||
! Poll to see if there's incoming data available.
 | 
			
		||||
 | 
			
		||||
.define __sys_rawpoll
 | 
			
		||||
.define __sys_rawpoll
 | 
			
		||||
__sys_rawpoll:
 | 
			
		||||
	ldb r0, __uart_status
 | 
			
		||||
	b.eq r0, #0, 1b
 | 
			
		||||
 | 
			
		||||
	mov r1, #AUX_MU_LSR_REG
 | 
			
		||||
	ld r0, (r1)
 | 
			
		||||
	and r0, #0x1 ! 0 if no data, 1 if data
 | 
			
		||||
1:
 | 
			
		||||
	b lr
 | 
			
		||||
 | 
			
		||||
! Receive a single byte.
 | 
			
		||||
 | 
			
		||||
.define __sys_rawread
 | 
			
		||||
__sys_rawread:
 | 
			
		||||
	ldb r0, __uart_status
 | 
			
		||||
	b.eq r0, #0, 1b
 | 
			
		||||
 | 
			
		||||
	! receive 1 byte (returned in r0)
 | 
			
		||||
	mov	r1, #AUX_MU_LSR_REG
 | 
			
		||||
	mov	r2, #AUX_MU_IO_REG
 | 
			
		||||
	! loop until char available
 | 
			
		||||
recvwait:
 | 
			
		||||
	ld r3, (r1)
 | 
			
		||||
	and	r3, #0x1
 | 
			
		||||
	b.ne r3, #0x1, recvwait
 | 
			
		||||
 | 
			
		||||
	ldb	r0, (r2)
 | 
			
		||||
1:
 | 
			
		||||
	b lr
 | 
			
		||||
 | 
			
		||||
.comm __uart_status, 1
 | 
			
		||||
 | 
			
		||||
.sect .data
 | 
			
		||||
.define _pi_clock_speed
 | 
			
		||||
 | 
			
		||||
! System clock is running directly off the 19.2MHz crystal at initial reset
 | 
			
		||||
_pi_clock_speed:
 | 
			
		||||
	.data4 19200000
 | 
			
		||||
							
								
								
									
										20
									
								
								plat/rpi/libsys/pi_user_to_phys.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								plat/rpi/libsys/pi_user_to_phys.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
#
 | 
			
		||||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "libsysasm.h"
 | 
			
		||||
 | 
			
		||||
.sect .text
 | 
			
		||||
 | 
			
		||||
! Transforms a user address into a physical address.
 | 
			
		||||
 | 
			
		||||
.define _pi_user_to_phys
 | 
			
		||||
_pi_user_to_phys:
 | 
			
		||||
	ld r0, 0 (sp)
 | 
			
		||||
	add r0, gp
 | 
			
		||||
	b lr
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								plat/rpi/libsys/read.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								plat/rpi/libsys/read.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include "libsys.h"
 | 
			
		||||
 | 
			
		||||
int read(int fd, void* buffer, size_t count)
 | 
			
		||||
{
 | 
			
		||||
	char i;
 | 
			
		||||
	
 | 
			
		||||
	/* We're only allowed to read from fd 0, 1 or 2. */
 | 
			
		||||
	
 | 
			
		||||
	if ((fd < 0) || (fd > 2))
 | 
			
		||||
	{
 | 
			
		||||
		errno = EBADF;
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* Empty buffer? */
 | 
			
		||||
	
 | 
			
		||||
	if (count == 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	
 | 
			
		||||
	/* Read one byte. */
 | 
			
		||||
	
 | 
			
		||||
	i = _sys_rawread();
 | 
			
		||||
	if ((i == '\r') && !(_sys_ttyflags & INLCR))
 | 
			
		||||
		i = '\n';
 | 
			
		||||
	if (_sys_ttyflags & ECHO)
 | 
			
		||||
		_sys_write_tty(i);
 | 
			
		||||
 | 
			
		||||
	*(char*)buffer = i;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								plat/rpi/libsys/select.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								plat/rpi/libsys/select.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <pi.h>
 | 
			
		||||
#include "libsys.h"
 | 
			
		||||
 | 
			
		||||
#define TICKS_PER_SEC 1000000
 | 
			
		||||
 | 
			
		||||
typedef int condition_t(void);
 | 
			
		||||
 | 
			
		||||
static int nop_condition(void)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int select(int nfds, fd_set *readfds, fd_set *writefds,
 | 
			
		||||
                  fd_set *exceptfds, struct timeval *timeout)
 | 
			
		||||
{
 | 
			
		||||
	int result = 0;
 | 
			
		||||
	condition_t* condition = nop_condition;
 | 
			
		||||
 | 
			
		||||
	if (FD_ISSET(0, readfds))
 | 
			
		||||
		condition = _sys_rawpoll;
 | 
			
		||||
 | 
			
		||||
	FD_ZERO(readfds);
 | 
			
		||||
	FD_ZERO(writefds);
 | 
			
		||||
	FD_ZERO(exceptfds);
 | 
			
		||||
 | 
			
		||||
	if (timeout)
 | 
			
		||||
	{
 | 
			
		||||
		/* Wait for a specified amount of time. */
 | 
			
		||||
 | 
			
		||||
		uint32_t ticks = (timeout->tv_sec * TICKS_PER_SEC) +
 | 
			
		||||
			(timeout->tv_usec * (TICKS_PER_SEC/1000000));
 | 
			
		||||
		uint32_t* timer_clo = pi_phys_to_user((void*) 0x7e003004);
 | 
			
		||||
		uint32_t ra = *timer_clo;
 | 
			
		||||
 | 
			
		||||
		while (!condition() && ((*timer_clo - ra) < ticks))
 | 
			
		||||
			;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* Wait forever. */
 | 
			
		||||
 | 
			
		||||
		while (!condition())
 | 
			
		||||
			;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((condition == _sys_rawpoll) && condition())
 | 
			
		||||
	{
 | 
			
		||||
		FD_SET(0, readfds);
 | 
			
		||||
		result = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								plat/rpi/libsys/signal.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								plat/rpi/libsys/signal.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include "libsys.h"
 | 
			
		||||
 | 
			
		||||
sighandler_t signal(int signum, sighandler_t handler)
 | 
			
		||||
{
 | 
			
		||||
	return SIG_DFL;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								plat/rpi/libsys/tcgetattr.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								plat/rpi/libsys/tcgetattr.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include "libsys.h"
 | 
			
		||||
 | 
			
		||||
int tcgetattr(int fd, struct termios* t)
 | 
			
		||||
{
 | 
			
		||||
    t->c_iflag = _sys_ttyflags & INLCR;
 | 
			
		||||
    t->c_oflag = _sys_ttyflags & ONLCR;
 | 
			
		||||
    t->c_lflag = _sys_ttyflags & ECHO;
 | 
			
		||||
    t->c_cflag = 0;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								plat/rpi/libsys/tcsetattr.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								plat/rpi/libsys/tcsetattr.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include "libsys.h"
 | 
			
		||||
 | 
			
		||||
int tcsetattr(int fd, int actions, struct termios* t)
 | 
			
		||||
{
 | 
			
		||||
	_sys_ttyflags = t->c_iflag | t->c_oflag | t->c_lflag;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								plat/rpi/libsys/time.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								plat/rpi/libsys/time.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include "libsys.h"
 | 
			
		||||
 | 
			
		||||
time_t time(time_t* t)
 | 
			
		||||
{
 | 
			
		||||
	if (t)
 | 
			
		||||
		*t = 0;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								plat/rpi/libsys/write.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								plat/rpi/libsys/write.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,49 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Raspberry Pi support library for the ACK
 | 
			
		||||
 * © 2013 David Given
 | 
			
		||||
 * This file is redistributable under the terms of the 3-clause BSD license.
 | 
			
		||||
 * See the file 'Copying' in the root of the distribution for the full text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include "libsys.h"
 | 
			
		||||
 | 
			
		||||
int _sys_ttyflags = ONLCR | INLCR | ECHO;
 | 
			
		||||
 | 
			
		||||
void _sys_write_tty(char c)
 | 
			
		||||
{
 | 
			
		||||
	_sys_rawwrite(c);
 | 
			
		||||
	if ((c == '\n') && (_sys_ttyflags & ONLCR))
 | 
			
		||||
		_sys_rawwrite('\r');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int write(int fd, void* buffer, size_t count)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	char* p = buffer;
 | 
			
		||||
	
 | 
			
		||||
	/* We're only allowed to write to fd 0, 1 or 2. */
 | 
			
		||||
	
 | 
			
		||||
	if ((fd < 0) || (fd > 2))
 | 
			
		||||
	{
 | 
			
		||||
		errno = EBADF;
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* Write all data. */
 | 
			
		||||
	
 | 
			
		||||
	i = 0;
 | 
			
		||||
	while (i < count)
 | 
			
		||||
	{
 | 
			
		||||
		_sys_write_tty(*p++);
 | 
			
		||||
			
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* No failures. */
 | 
			
		||||
	
 | 
			
		||||
	return count;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +143,9 @@ showrelo()
 | 
			
		|||
	case RELOH2:
 | 
			
		||||
		printf("\ttop 2 bytes of a 4 byte word\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case RELOVC4:
 | 
			
		||||
		printf("\tVideoCore IV address in 32-bit instruction\n");
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		printf("\tunknown relocation type %d\n", relrec.or_type & RELSZ);
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -164,6 +164,7 @@ struct outrelo {
 | 
			
		|||
#define RELO4	0x03		/* 4 bytes */
 | 
			
		||||
#define RELOPPC	0x04		/* 26-bit PowerPC address */
 | 
			
		||||
#define RELOH2  0x05        /* write top 2 bytes of 4 byte word */
 | 
			
		||||
#define RELOVC4 0x06        /* VideoCore IV address in 32-bit insruction */
 | 
			
		||||
#define RELPC	0x08		/* pc relative */
 | 
			
		||||
#define RELBR	0x10		/* High order byte lowest address. */
 | 
			
		||||
#define RELWR	0x20		/* High order word lowest address. */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,8 @@ static char rcsid[] = "$Id$";
 | 
			
		|||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include "out.h"
 | 
			
		||||
#include "const.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +45,65 @@ static long read4(char* addr, int type)
 | 
			
		|||
		return ((long)word1 << (2 * WIDTH)) + word0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* VideoCore 4 fixups are complex as we need to patch the instruction in
 | 
			
		||||
 * one of several different ways (depending on what the instruction is).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static long get_vc4_valu(char* addr)
 | 
			
		||||
{
 | 
			
		||||
	uint16_t opcode = read2(addr, 0);
 | 
			
		||||
 | 
			
		||||
	if ((opcode & 0xff00) == 0xe700)
 | 
			
		||||
	{
 | 
			
		||||
		/* ld<w> rd, $+o:  [1110 0111 ww 0 d:5] [11111 o:27]
 | 
			
		||||
		 * st<w> rd, $+o:  [1110 0111 ww 1 d:5] [11111 o:27]
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
		int32_t value = read4(addr+2, 0);
 | 
			
		||||
		value &= 0x07ffffff;
 | 
			
		||||
		value = value<<5>>5;
 | 
			
		||||
		return value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((opcode & 0xf080) == 0x9000)
 | 
			
		||||
	{
 | 
			
		||||
		/* b<cc> $+o*2:  [1001 cccc 0ooo oooo] [oooo oooo oooo oooo]
 | 
			
		||||
		 * Yes, big-endian (the first 16 bits is the MSB).
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
		uint32_t value = read4(addr, RELWR);
 | 
			
		||||
		value &= 0x007fffff;
 | 
			
		||||
		value = value<<9>>9;
 | 
			
		||||
		value *= 2;
 | 
			
		||||
		return value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((opcode & 0xf080) == 0x9080)
 | 
			
		||||
	{
 | 
			
		||||
		/* bl $+o*2:  [1001 oooo 1ooo oooo] [oooo oooo oooo oooo]
 | 
			
		||||
		 * Yes, big-endian (the first 16 bits is the MSB).
 | 
			
		||||
		 * (Note that o is split.)
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
		int32_t value = read4(addr, RELWR);
 | 
			
		||||
		int32_t lov = value & 0x007fffff;
 | 
			
		||||
		int32_t hiv = value & 0x0f000000;
 | 
			
		||||
		value = lov | (hiv>>1);
 | 
			
		||||
		value = value<<5>>5;
 | 
			
		||||
		value *= 2;
 | 
			
		||||
		return value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((opcode & 0xffe0) == 0xe500)
 | 
			
		||||
	{
 | 
			
		||||
        /* lea: [1110 0101 000 d:5] [o:32] */
 | 
			
		||||
 | 
			
		||||
        return read4(addr+2, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	assert(0 && "unrecognised VC4 instruction");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The bits in type indicate how many bytes the value occupies and what
 | 
			
		||||
 * significance should be attributed to each byte.
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +124,8 @@ getvalu(addr, type)
 | 
			
		|||
		return read4(addr, type) & 0x03FFFFFD;
 | 
			
		||||
	case RELOH2:
 | 
			
		||||
		return read2(addr, type) << 16;
 | 
			
		||||
	case RELOVC4:
 | 
			
		||||
		return get_vc4_valu(addr);
 | 
			
		||||
	default:
 | 
			
		||||
		fatal("bad relocation size");
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +169,60 @@ static void write4(long valu, char* addr, int type)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* VideoCore 4 fixups are complex as we need to patch the instruction in
 | 
			
		||||
 * one of several different ways (depending on what the instruction is).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static void put_vc4_valu(char* addr, long value)
 | 
			
		||||
{
 | 
			
		||||
	uint16_t opcode = read2(addr, 0);
 | 
			
		||||
 | 
			
		||||
	if ((opcode & 0xff00) == 0xe700)
 | 
			
		||||
	{
 | 
			
		||||
		/* ld<w> rd, o, (pc):  [1110 0111 ww 0 d:5] [11111 o:27]
 | 
			
		||||
		 * st<w> rd, o, (pc):  [1110 0111 ww 1 d:5] [11111 o:27]
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
		uint32_t v = read4(addr+2, 0);
 | 
			
		||||
		v &= 0xf8000000;
 | 
			
		||||
		v |= value & 0x07ffffff;
 | 
			
		||||
		write4(v, addr+2, 0);
 | 
			
		||||
	}
 | 
			
		||||
	else if ((opcode & 0xf080) == 0x9000)
 | 
			
		||||
	{
 | 
			
		||||
		/* b<cc> dest:  [1001 cccc 0ooo oooo] [oooo oooo oooo oooo]
 | 
			
		||||
		 * Yes, big-endian (the first 16 bits is the MSB).
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
		uint32_t v = read4(addr, RELWR);
 | 
			
		||||
		v &= 0xff800000;
 | 
			
		||||
		v |= (value/2) & 0x007fffff;
 | 
			
		||||
		write4(v, addr, RELWR);
 | 
			
		||||
	}
 | 
			
		||||
	else if ((opcode & 0xf080) == 0x9080)
 | 
			
		||||
	{
 | 
			
		||||
		/* bl dest:  [1001 oooo 1ooo oooo] [oooo oooo oooo oooo]
 | 
			
		||||
		 * Yes, big-endian (the first 16 bits is the MSB).
 | 
			
		||||
		 * (Note that o is split.)
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
		uint32_t v = read4(addr, RELWR);
 | 
			
		||||
		uint32_t lovalue = (value/2) & 0x007fffff;
 | 
			
		||||
		uint32_t hivalue = (value/2) & 0x07800000;
 | 
			
		||||
		v &= 0xf0800000;
 | 
			
		||||
		v |= lovalue | (hivalue<<1);
 | 
			
		||||
		write4(v, addr, RELWR);
 | 
			
		||||
	}
 | 
			
		||||
	else if ((opcode & 0xffe0) == 0xe500)
 | 
			
		||||
	{
 | 
			
		||||
        /* lea: [1110 0101 000 d:5] [o:32] */
 | 
			
		||||
 | 
			
		||||
		write4(value, addr+2, 0);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
		assert(0 && "unrecognised VC4 instruction");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The bits in type indicate how many bytes the value occupies and what
 | 
			
		||||
 * significance should be attributed to each byte.
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +255,9 @@ putvalu(valu, addr, type)
 | 
			
		|||
	case RELOH2:
 | 
			
		||||
		write2(valu>>16, addr, type);
 | 
			
		||||
		break;
 | 
			
		||||
	case RELOVC4:
 | 
			
		||||
		put_vc4_valu(addr, valu);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		fatal("bad relocation size");
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue