Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • kratot13/stud-support
  • krotima1/stud-support
  • khomumik/stud-support
  • vondrm28/stud-support
  • b35apo/stud-support
  • sehnakar/stud-support
  • chiuyuwe/stud-support
  • dupakjak/stud-support
  • pucekrad/stud-support
  • zampadan/stud-support
  • pelikon1/stud-support
  • perailuk/stud-support
  • gorbuden/stud-support
  • ponomnaz/stud-support
  • kiselnik/stud-support
  • neslusam/stud-support
  • galkidmi/stud-support
  • yuanweiz/stud-support
  • benckmar/stud-support
  • chvatond/stud-support
  • frysakat/stud-support
  • juzaluk2/stud-support
  • bobenade/stud-support
  • mikusvad/stud-support
  • romanrom/stud-support
  • kimdawon/stud-support
  • koblirad/stud-support
  • rachkiev/stud-support
  • forczsan/stud-support
  • vaginars/stud-support
  • kolarve8/stud-support
  • zyryadan/stud-support
  • myrzaami/stud-support
33 results
Show changes
Commits on Source (21)
Showing
with 1344 additions and 0 deletions
*.o
*.dump
*-native
*-x86
*-riscv
*-riscv64
*-mips
*-arm
*-aarch64
# Makefile to buidl example for different ISA targets
# Select architecture by ARCH parameter
# native, x86, riscv, riscv64, mips, arm, aarch64
# Specify source files of the program
SOURCES = hello-apo.c
# Specify base name of the executable - architecture
TARGET_BASE = hello-apo
# The actual target filename is unique for each architecture
TARGET_EXE = $(TARGET_BASE)-$(ARCH)
all: default
.PHONY : all default build run dump clean
ARCH_SUPPORTED = native x86 riscv riscv64 mips arm aarch64
ifneq ($(MAKECMDGOALS),clean)
ifeq ($(filter $(ARCH_SUPPORTED),$(ARCH)),)
$(error ARCH parameter has to be set accepted: x86, riscv, riscv64, mips and arm)
endif
endif
# setting specific for riscv build for native build
SOURCES-native +=
LOADLIBES-native +=
CC-native = gcc
OBJDUMP-native = objdump
ARCHFLAGS-native += -ggdb
RUN-native =
# setting specific for riscv build for native build
SOURCES-x86 +=
LOADLIBES-x86 +=
CC-x86 = x86_64-linux-gnu-gcc
OBJDUMP-x86 = x86_64-linux-gnu-objdump
ARCHFLAGS-native += -static -ggdb
RUN-x86 = qemu-x86_64-static
# setting specific for riscv build for QtRvSim simulator and or RISC-V Linux 32-bit run
SOURCES-riscv += sys-qtrvsim/qtrvsim_sys_stub.c sys-qtrvsim/crt0local.S
LOADLIBES-riscv += -lc -lgcc
CC-riscv = riscv64-unknown-elf-gcc
OBJDUMP-riscv = riscv64-unknown-elf-objdump
ARCHFLAGS-riscv += -mabi=ilp32 -march=rv32im -fno-lto -nostartfiles -nostdlib -static -ggdb
RUN-riscv = qemu-riscv32-static
# setting specific for riscv64 build for QtRvSim simulator and or RISC-V Linux 64-bit run
SOURCES-riscv64 += sys-qtrvsim/qtrvsim_sys_stub.c sys-qtrvsim/crt0local.S
LOADLIBES-riscv64 += -lc -lgcc
CC-riscv64 = riscv64-unknown-elf-gcc
OBJDUMP-riscv64 = riscv64-unknown-elf-objdump
ARCHFLAGS-riscv64 += -mabi=lp64 -march=rv64imac -fno-lto -nostartfiles -nostdlib -static -ggdb
RUN-riscv64 = qemu-riscv64-static
# setting specific for riscv64 build for QtMips simulator and or MIPS Linux run
SOURCES-mips += sys-qtmips/qtmips_sys_stub.c sys-qtmips/crt0local.S
LOADLIBES-mips += -lc -lgcc
CC-mips = mips-elf-gcc
OBJDUMP-mips = mips-elf-objdump
ARCHFLAGS-mips += -march=mips32 -fno-lto -nostartfiles -nostdlib -static -ggdb
RUN-mips = qemu-mips-static
# setting specific for ARM 32-bit build
SOURCES-arm +=
LOADLIBES-arm +=
CC-arm = arm-linux-gnueabihf-gcc
OBJDUMP-arm = arm-linux-gnueabihf-objdump
ARCHFLAGS-arm += -static -ggdb
RUN-arm = qemu-arm-static
# setting specific for ARM 64-bit build
SOURCES-aarch64 +=
LOADLIBES-aarch64 +=
CC-aarch64 = aarch64-linux-gnu-gcc
OBJDUMP-aarch64 = aarch64-linux-gnu-objdump
ARCHFLAGS-aarch64 += -static -ggdb
RUN-aarch64 = qemu-aarch64-static
define compile_one_src
src := $(1)
arch := $(2)
obj := $$(basename $$(notdir $$(src)))-$$(arch).o
$$(obj) : $$(src)
$$(CC-$$(arch)) $$(ARCHFLAGS-$$(arch)) -c $$< -o $$@
OBJS-$$(arch) := $$(OBJS-$$(arch)) $$(obj)
#$$(warning $$(src) $$(obj) $$(arch) $$(OBJS-$$(arch)))
endef
$(foreach srci, $(SOURCES) $(SOURCES-$(ARCH)),$(eval $(call compile_one_src, $(srci), $(ARCH))))
$(TARGET_EXE) : $(OBJS-$(ARCH))
$(CC-$(ARCH)) -o $@ $^ $(ARCHFLAGS-$(ARCH)) $(LOADLIBES-$(ARCH))
build : $(TARGET_EXE)
run : $(TARGET_EXE)
$(RUN-$(ARCH)) ./$<
dump: $(TARGET_EXE)
$(OBJDUMP-$(ARCH)) --source $< > $<.dump
cat $<.dump
clean :
rm -f $(OBJS-$(ARCH)) $(foreach arch,$(ARCH_SUPPORTED),$(TARGET_BASE)-$(arch)) *.o *.dump
default : build
\ No newline at end of file
/* Hello world example to demonstrate on multiple architectures */
/*
* compile, run and examine for different instruction set architectures
* build by make command where ARCH is chisen as one of
* native, x86, riscv, riscv64, mips, arm or aarch64
* make ARCH=riscv
*/
#include <stdio.h>
//int var_a = 40;
//int var_b = 2;
int main(int argc, char *argv[])
{
/*
* modify program to compute and print answer
* of var_a + var_b
*/
printf("Hello APO\n");
return 0;
}
/* minimal replacement of crt0.o which is else provided by C library */
.globl main
.globl _start
.globl __start
.globl _heap_stack_start
.globl _heap_stack_end
.set noat
.set noreorder
.ent _start
.text
__start:
_start:
#if defined(__PIC__) || defined(__pic__)
bal next
nop
next:
.set noreorder
.cpload $31
.set reorder
#else
la $gp, _gp
#endif
la $sp, _heap_stack_end
addi $a0, $zero, 0
addi $a1, $zero, 0
jal main
nop
quit:
addi $a0, $zero, 0
addi $v0, $zero, 4001 /* SYS_exit */
syscall
loop: break
beq $zero, $zero, loop
nop
.end _start
.bss
_heap_stack_start:
.skip 0x800000
_heap_stack_end:
/* Support files for GNU libc. Files in the system namespace go here.
Files in the C namespace (ie those that do not start with an
underscore) go in .c. */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
#include <errno.h>
#include <reent.h>
#include "qtmips_unistd.h"
#define UNUSED_PARAM(symbol) ((void)(symbol))
/* Register name - works in collusion with the linker. */
register char * stack_ptr asm ("sp");
int _read(int file, char *ptr, int len);
int
_read (int file,
char * ptr,
int len)
{
register int __v0 asm("$v0") = __NR_read;
register int __a0 asm("$a0") = file;
register char * __a1 asm("$a1") = ptr;
register int __a2 asm("$a2") = len;
register int __a3 asm("$a3");
__asm__ volatile (
".set\tnoreorder\n\t"
"syscall\n\t"
".set reorder"
: "=r" (__v0), "=r" (__a3)
: "r" (__v0), "r" (__a0), "r" (__a1), "r"(__a2)
: );
return __a3? -1: __v0;
}
int _write(int file, const char *ptr, int len);
int
_write (int file,
const char * ptr,
int len)
{
register int __v0 asm("$v0") = __NR_write;
register int __a0 asm("$a0") = file;
register const char * __a1 asm("$a1") = ptr;
register int __a2 asm("$a2") = len;
register int __a3 asm("$a3");
__asm__ volatile (
".set\tnoreorder\n\t"
"syscall\n\t"
".set reorder"
: "=r" (__v0), "=r" (__a3)
: "r" (__v0), "r" (__a0), "r" (__a1), "r"(__a2)
: );
return __a3? -1: __v0;
}
int
_lseek (int file,
int pos,
int dir)
{
UNUSED_PARAM(file);
UNUSED_PARAM(pos);
UNUSED_PARAM(dir);
return -1;
}
int _open(const char *path, int flags, ...);
int
_open (const char * path,
int flags,
...)
{
register int __v0 asm("$v0") = __NR_open;
register const char * __a0 asm("$a0") = path;
register int __a1 asm("$a1") = flags;
register int __a2 asm("$a2") = 0;
register int __a3 asm("$a3");
if (flags & O_CREAT) {
va_list list;
va_start(list, flags);
__a2 = va_arg(list, int);
va_end(list);
}
__asm__ volatile (
".set\tnoreorder\n\t"
"syscall\n\t"
".set reorder"
: "=r" (__v0), "=r" (__a3)
: "r" (__v0), "r" (__a0), "r" (__a1), "r"(__a2)
: );
return __a3? -1: __v0;
}
int _close(int file);
int
_close (int file)
{
register int __v0 asm("$v0") = __NR_close;
register int __a0 asm("$a0") = file;
register int __a3 asm("$a3");
__asm__ volatile (
".set\tnoreorder\n\t"
"syscall\n\t"
".set reorder"
: "=r" (__v0), "=r" (__a3)
: "r" (__v0), "r" (__a0)
: );
return __a3? -1: __v0;
}
void _exit(int n);
void
_exit (int n)
{
register int __v0 asm("$v0") = __NR_exit;
register int __a0 asm("$a0") = n;
while(1) __asm__ volatile (
".set\tnoreorder\n\t"
"syscall\n\t"
".set reorder"
:
: "r" (__v0), "r" (__a0)
: "a3");
}
void abort(void);
void abort(void)
{
while(1) __asm__ volatile (
".set\tnoreorder\n\t"
"break\n\t"
".set reorder"
:
:
: );
}
int _kill(int n, int m);
int
_kill (int n, int m)
{
UNUSED_PARAM(n);
UNUSED_PARAM(m);
return -1;
}
int _getpid(void);
int
_getpid (void)
{
return 1;
}
void *_sbrk(ptrdiff_t incr);
void *
_sbrk (ptrdiff_t incr)
{
extern char _heap_stack_start;
static char *heap_end;
char * prev_heap_end;
incr=(incr+3) & ~3;
if (heap_end == NULL)
heap_end = & _heap_stack_start;
prev_heap_end = heap_end;
if ((heap_end + incr > stack_ptr) && (&_heap_stack_start < stack_ptr))
{
/* Some of the libstdc++-v3 tests rely upon detecting
out of memory errors, so do not abort here. */
#if 1
extern void abort (void);
_write (1, "_sbrk: Heap and stack collision\n", 32);
abort ();
#else
errno = ENOMEM;
return (caddr_t) -1;
#endif
}
heap_end += incr;
return /*(caddr_t)*/ prev_heap_end;
}
int _fstat(int file, struct stat *st);
int
_fstat (int file, struct stat * st)
{
UNUSED_PARAM(file);
UNUSED_PARAM(st);
return -1;
}
int _stat (const char *fname, struct stat *st);
int _stat (const char *fname, struct stat *st)
{
UNUSED_PARAM(fname);
UNUSED_PARAM(st);
return -1;
}
int _link(const char *path1, const char *path2);
int
_link (const char *path1,
const char *path2)
{
UNUSED_PARAM(path1);
UNUSED_PARAM(path2);
return -1;
}
int _unlink(const char *path);
int
_unlink (const char *path)
{
UNUSED_PARAM(path);
return -1;
}
void _raise(void);
void
_raise (void)
{
return;
}
int _gettimeofday(struct timeval *tp, struct timezone *tzp);
int
_gettimeofday (struct timeval *tp,
struct timezone *tzp)
{
if(tp)
{
tp->tv_sec = 0;
tp->tv_usec = 0;
}
/* Return fixed data for the timezone. */
if (tzp)
{
tzp->tz_minuteswest = 0;
tzp->tz_dsttime = 0;
}
return 0;
}
/* Return a clock that ticks at 100Hz. */
clock_t _times(struct tms *tp);
clock_t
_times (struct tms * tp)
{
clock_t timeval = 0;
if (tp)
{
tp->tms_utime = timeval; /* user time */
tp->tms_stime = 0; /* system time */
tp->tms_cutime = 0; /* user time, children */
tp->tms_cstime = 0; /* system time, children */
}
return timeval;
};
int isatty(int fd);
int
isatty (int fd)
{
UNUSED_PARAM(fd);
return 1;
}
int _system(const char *s);
int
_system (const char *s)
{
UNUSED_PARAM(s);
return -1;
}
int _rename(const char *oldpath, const char *newpath);
int
_rename (const char * oldpath, const char * newpath)
{
UNUSED_PARAM(oldpath);
UNUSED_PARAM(newpath);
return -1;
}
/* extern (.*) ([^ ]*) _PARAMS \(\(struct _reent \*(,*)(.*)\)\); */
/* \1 \2 (struct _reent *\3\4) { return \2(\4);} */
struct _reent;
int _close_r(struct _reent *reent, int file)
{ UNUSED_PARAM(reent); return _close(file);}
/*
int _fcntl_r(struct _reent *, int, int, int)
{ return _fcntl( int, int, int);}
*/
int _fstat_r(struct _reent *reent, int file, struct stat *st);
int _fstat_r(struct _reent *reent, int file, struct stat *st)
{ UNUSED_PARAM(reent); return _fstat(file, st);}
int _getpid_r(struct _reent *reent);
int _getpid_r(struct _reent *reent)
{ UNUSED_PARAM(reent); return _getpid();}
int _kill_r(struct _reent *reent, int n, int m);
int _kill_r(struct _reent *reent, int n, int m)
{ UNUSED_PARAM(reent); return _kill(n, m);}
int _link_r(struct _reent *reent, const char *path1, const char *path2);
int _link_r(struct _reent *reent, const char *path1, const char *path2)
{ UNUSED_PARAM(reent); return _link(path1, path2);}
_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir);
_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir)
{ UNUSED_PARAM(reent); return _lseek(file, pos, dir);}
int _open_r(struct _reent *reent, const char *path, int flags, int opts);
int _open_r(struct _reent *reent, const char *path, int flags, int opts)
{ UNUSED_PARAM(reent); return _open(path, flags, opts);}
_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len);
_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len)
{ UNUSED_PARAM(reent); return _read(file, ptr, len);}
void *_sbrk_r(struct _reent *reent, ptrdiff_t incr);
void *_sbrk_r(struct _reent *reent, ptrdiff_t incr)
{ UNUSED_PARAM(reent); return _sbrk(incr);}
int _stat_r(struct _reent *reent, const char *path, struct stat *st);
int _stat_r(struct _reent *reent, const char *path, struct stat *st)
{ UNUSED_PARAM(reent); return _stat(path, st);}
int _unlink_r(struct _reent *reent, const char *path);
int _unlink_r(struct _reent *reent, const char *path)
{ UNUSED_PARAM(reent); return _unlink(path);}
_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len);
_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len)
{ UNUSED_PARAM(reent); return _write(file, ptr, len);}
/* FIXME: TDK added dummy functions. Need to implement. */
int _isatty(int fd);
int _isatty(int fd)
{
UNUSED_PARAM(fd);
return -1;
}
int _swistat(int fd, struct stat *st);
int _swistat(int fd, struct stat *st)
{
UNUSED_PARAM(fd);
UNUSED_PARAM(st);
return -1;
}
/* Return a clock that ticks at 100Hz. */
clock_t _clock(void);
clock_t _clock(void)
{
clock_t timeval=0;
return timeval;
}
int _swiclose(int fh);
int _swiclose(int fh)
{
UNUSED_PARAM(fh);
return -1;
}
int _swiopen(const char *path, int flags);
int _swiopen(const char *path, int flags)
{
UNUSED_PARAM(path);
UNUSED_PARAM(flags);
return -1;
}
int _swiwrite(int fh, char *ptr, int len);
int _swiwrite(int fh, char *ptr, int len)
{
UNUSED_PARAM(fh);
UNUSED_PARAM(ptr);
UNUSED_PARAM(len);
return -1;
}
int _swilseek(int fd, int ptr, int dir);
int _swilseek(int fd, int ptr, int dir)
{
UNUSED_PARAM(fd);
UNUSED_PARAM(ptr);
UNUSED_PARAM(dir);
return -1;
}
int _swiread(int fh, char *ptr, int len);
int _swiread(int fh, char *ptr, int len)
{
UNUSED_PARAM(fh);
UNUSED_PARAM(ptr);
UNUSED_PARAM(len);
return -1;
}
void initialise_monitor_handles(void);
void initialise_monitor_handles(void)
{
}
// ******************************************************************
// QtMips emulator https://github.com/cvut/QtMips support filees
//
// qtmips_unistd.h - definition of the QtMips syscall numbers
//
// (C) Copyright 2019 - 2020 by Pavel Pisa
// e-mail: pisa@cmp.felk.cvut.cz
// homepage: http://cmp.felk.cvut.cz/~pisa
// license: any combination of GPL, LGPL, MPL or BSD licenses
//
// ******************************************************************
#ifndef QTMIPS_UNISTD_H
#define QTMIPS_UNISTD_H
// Linux kernel compatible system calls subset
#define __NR_exit 4001 // void exit(int status)
#define __NR_read 4003 // ssize_t read(int fd, void *buf, size_t count)
#define __NR_write 4004 // ssize_t write(int fd, const void *buf, size_t count)
#define __NR_close 4006 // int close(int fd)
#define __NR_open 4005 // int open(const char *pathname, int flags, mode_t mode)
#define __NR_brk 4045 // void * brk(void *addr)
#define __NR_truncate 4092 // int ftruncate(int fd, off_t length)
#define __NR_readv 4145 // ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
#define __NR_writev 4146 // ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
#define __NR_set_thread_area 4283 // int set_thread_area(unsigned long addr)
#endif /*QTMIPS_UNISTD_H*/
/* minimal replacement of crt0.o which is else provided by C library */
.globl main
.globl _start
.globl __start
.globl _heap_stack_start
.globl _heap_stack_end
.option norelax
.text
__start:
_start:
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _heap_stack_end
addi a0, zero, 0
addi a1, zero, 0
jal main
quit:
addi a0, zero, 0
addi a7, zero, 93 /* SYS_exit */
ecall
loop: ebreak
beq zero, zero, loop
.bss
_heap_stack_start:
.skip 16384
_heap_stack_end:
.end _start
/* Support files for GNU libc. Files in the system namespace go here.
Files in the C namespace (ie those that do not start with an
underscore) go in .c. */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
#include <errno.h>
#include <reent.h>
#include "qtrvsim_unistd.h"
#define UNUSED_PARAM(symbol) ((void)(symbol))
/* Open flags definition for Linux kernel copied from musl-libc */
#define KERNEL_O_CREAT 0100
#define KERNEL_O_EXCL 0200
#define KERNEL_O_NOCTTY 0400
#define KERNEL_O_TRUNC 01000
#define KERNEL_O_APPEND 02000
#define KERNEL_O_NONBLOCK 04000
#define KERNEL_O_DSYNC 010000
#define KERNEL_O_SYNC 04010000
#define KERNEL_O_RSYNC 04010000
#define KERNEL_O_DIRECTORY 0200000
#define KERNEL_O_NOFOLLOW 0400000
#define KERNEL_O_CLOEXEC 02000000
#define KERNEL_O_PATH 010000000
#define KERNEL_O_SYNC1 040000
#define KERNEL_O_ACCMODE (03 | KERNEL_O_PATH)
#define KERNEL_O_RDONLY 00
#define KERNEL_O_WRONLY 01
#define KERNEL_O_RDWR 02
#define TARGET_AT_FDCWD -100
/* Register name - works in collusion with the linker. */
register char * stack_ptr asm ("sp");
int _read(int file, char *ptr, int len);
int
_read (int file,
char * ptr,
int len)
{
register int __a7 asm("a7") = __NR_read;
register int __a0 asm("a0") = file;
register char * __a1 asm("a1") = ptr;
register int __a2 asm("a2") = len;
__asm__ volatile (
"ecall\n\t"
: "=r" (__a0)
: "r" (__a7), "r" (__a0), "r" (__a1), "r"(__a2)
: );
return __a0 < 0 ? -1: __a0;
}
int _write(int file, const char *ptr, int len);
int
_write (int file,
const char * ptr,
int len)
{
register int __a7 asm("a7") = __NR_write;
register int __a0 asm("a0") = file;
register const char * __a1 asm("a1") = ptr;
register int __a2 asm("a2") = len;
__asm__ volatile (
"ecall\n\t"
: "=r" (__a0)
: "r" (__a7), "r" (__a0), "r" (__a1), "r"(__a2)
: );
return __a0 < 0 ? -1: __a0;
}
int
_lseek (int file,
int pos,
int dir)
{
UNUSED_PARAM(file);
UNUSED_PARAM(pos);
UNUSED_PARAM(dir);
return -1;
}
int _openat(int fd, const char *path, int flags, ...);
int
_openat (int fd, const char * path,
int flags,
...)
{
register int __a7 asm("a7") = __NR_openat;
// use fd = -100 for normal open behaviour. Full openat not supported.
register int __a0 asm("a0") = fd;
register const char * __a1 asm("a1") = path;
register int __a2 asm("a2") = 0;
register int __a3 asm("a3");
#ifdef O_CREAT
if (flags & O_CREAT)
__a2 |= KERNEL_O_CREAT;
#endif
#ifdef O_EXCL
if (flags & O_EXCL)
__a2 |= KERNEL_O_EXCL;
#endif
#ifdef O_NOCTTY
if (flags & O_NOCTTY)
__a2 |= KERNEL_O_NOCTTY;
#endif
#ifdef O_TRUNC
if (flags & O_TRUNC)
__a2 |= KERNEL_O_TRUNC;
#endif
#ifdef O_APPEND
if (flags & O_APPEND)
__a2 |= KERNEL_O_APPEND;
#endif
#ifdef O_NONBLOCK
if (flags & O_NONBLOCK)
__a2 |= KERNEL_O_NONBLOCK;
#endif
#ifdef O_DSYNC
if (flags & O_DSYNC)
__a2 |= KERNEL_O_DSYNC;
#endif
#ifdef O_SYNC
if (flags & O_SYNC)
__a2 |= KERNEL_O_SYNC;
#endif
#ifdef O_RSYNC
if (flags & O_RSYNC)
__a2 |= KERNEL_O_RSYNC;
#endif
#ifdef O_DIRECTORY
if (flags & O_DIRECTORY)
__a2 |= KERNEL_O_DIRECTORY;
#endif
#ifdef O_NOFOLLOW
if (flags & O_NOFOLLOW)
__a2 |= KERNEL_O_NOFOLLOW;
#endif
#ifdef O_CLOEXEC
if (flags & O_CLOEXEC)
__a2 |= KERNEL_O_CLOEXEC;
#endif
if (flags & O_CREAT) {
va_list list;
va_start(list, flags);
__a3 = va_arg(list, int);
va_end(list);
}
__asm__ volatile (
"ecall\n\t"
: "=r" (__a0)
: "r" (__a7), "r" (__a0), "r" (__a1), "r"(__a2), "r"(__a3)
: );
return __a0 < 0 ? -1: __a0;
}
int _close(int file);
int
_close (int file)
{
register int __a7 asm("a7") = __NR_close;
register int __a0 asm("a0") = file;
__asm__ volatile (
"ecall\n\t"
: "=r" (__a0)
: "r" (__a7), "r" (__a0)
: );
return __a0 < 0 ? -1: __a0;
}
void _exit(int n);
void
_exit (int n)
{
register int __a7 asm("a7") = __NR_exit;
register int __a0 asm("a0") = n;
while(1) __asm__ volatile (
"ecall\n\t"
:
: "r" (__a7), "r" (__a0)
: );
}
void abort(void);
void abort(void)
{
while(1) __asm__ volatile (
"ebreak\n\t"
:
:
: );
}
int _kill(int n, int m);
int
_kill (int n, int m)
{
UNUSED_PARAM(n);
UNUSED_PARAM(m);
return -1;
}
int _getpid(void);
int
_getpid (void)
{
return 1;
}
void *_sbrk(ptrdiff_t incr);
void *
_sbrk (ptrdiff_t incr)
{
extern char _heap_stack_start;
static char *heap_end;
char * prev_heap_end;
incr=(incr+3) & ~3;
if (heap_end == NULL)
heap_end = & _heap_stack_start;
prev_heap_end = heap_end;
if ((heap_end + incr > stack_ptr) && (&_heap_stack_start < stack_ptr))
{
/* Some of the libstdc++-v3 tests rely upon detecting
out of memory errors, so do not abort here. */
#if 1
extern void abort (void);
_write (1, "_sbrk: Heap and stack collision\n", 32);
abort ();
#else
errno = ENOMEM;
return (caddr_t) -1;
#endif
}
heap_end += incr;
return /*(caddr_t)*/ prev_heap_end;
}
int _fstat(int file, struct stat *st);
int
_fstat (int file, struct stat * st)
{
UNUSED_PARAM(file);
UNUSED_PARAM(st);
return -1;
}
int _stat (const char *fname, struct stat *st);
int _stat (const char *fname, struct stat *st)
{
UNUSED_PARAM(fname);
UNUSED_PARAM(st);
return -1;
}
int _link(const char *path1, const char *path2);
int
_link (const char *path1,
const char *path2)
{
UNUSED_PARAM(path1);
UNUSED_PARAM(path2);
return -1;
}
int _unlink(const char *path);
int
_unlink (const char *path)
{
UNUSED_PARAM(path);
return -1;
}
void _raise(void);
void
_raise (void)
{
return;
}
int _gettimeofday(struct timeval *tp, struct timezone *tzp);
int
_gettimeofday (struct timeval *tp,
struct timezone *tzp)
{
if(tp)
{
tp->tv_sec = 0;
tp->tv_usec = 0;
}
/* Return fixed data for the timezone. */
if (tzp)
{
tzp->tz_minuteswest = 0;
tzp->tz_dsttime = 0;
}
return 0;
}
/* Return a clock that ticks at 100Hz. */
clock_t _times(struct tms *tp);
clock_t
_times (struct tms * tp)
{
clock_t timeval = 0;
if (tp)
{
tp->tms_utime = timeval; /* user time */
tp->tms_stime = 0; /* system time */
tp->tms_cutime = 0; /* user time, children */
tp->tms_cstime = 0; /* system time, children */
}
return timeval;
};
int isatty(int fd);
int
isatty (int fd)
{
UNUSED_PARAM(fd);
return 1;
}
int _system(const char *s);
int
_system (const char *s)
{
UNUSED_PARAM(s);
return -1;
}
int _rename(const char *oldpath, const char *newpath);
int
_rename (const char * oldpath, const char * newpath)
{
UNUSED_PARAM(oldpath);
UNUSED_PARAM(newpath);
return -1;
}
/* extern (.*) ([^ ]*) _PARAMS \(\(struct _reent \*(,*)(.*)\)\); */
/* \1 \2 (struct _reent *\3\4) { return \2(\4);} */
struct _reent;
int _close_r(struct _reent *reent, int file)
{ UNUSED_PARAM(reent); return _close(file);}
/*
int _fcntl_r(struct _reent *, int, int, int)
{ return _fcntl( int, int, int);}
*/
int _fstat_r(struct _reent *reent, int file, struct stat *st);
int _fstat_r(struct _reent *reent, int file, struct stat *st)
{ UNUSED_PARAM(reent); return _fstat(file, st);}
int _getpid_r(struct _reent *reent);
int _getpid_r(struct _reent *reent)
{ UNUSED_PARAM(reent); return _getpid();}
int _kill_r(struct _reent *reent, int n, int m);
int _kill_r(struct _reent *reent, int n, int m)
{ UNUSED_PARAM(reent); return _kill(n, m);}
int _link_r(struct _reent *reent, const char *path1, const char *path2);
int _link_r(struct _reent *reent, const char *path1, const char *path2)
{ UNUSED_PARAM(reent); return _link(path1, path2);}
_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir);
_off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir)
{ UNUSED_PARAM(reent); return _lseek(file, pos, dir);}
int _open_r(struct _reent *reent, const char *path, int flags, int opts);
int _open_r(struct _reent *reent, const char *path, int flags, int opts)
{ UNUSED_PARAM(reent); return _openat(TARGET_AT_FDCWD, path, flags, opts);}
int _openat_r(struct _reent *reent, int fd, const char *path, int flags, int opts);
int _openat_r(struct _reent *reent, int fd, const char *path, int flags, int opts)
{ UNUSED_PARAM(reent); return _openat(fd, path, flags, opts);}
_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len);
_ssize_t _read_r(struct _reent *reent, int file, void *ptr, size_t len)
{ UNUSED_PARAM(reent); return _read(file, ptr, len);}
void *_sbrk_r(struct _reent *reent, ptrdiff_t incr);
void *_sbrk_r(struct _reent *reent, ptrdiff_t incr)
{ UNUSED_PARAM(reent); return _sbrk(incr);}
int _stat_r(struct _reent *reent, const char *path, struct stat *st);
int _stat_r(struct _reent *reent, const char *path, struct stat *st)
{ UNUSED_PARAM(reent); return _stat(path, st);}
int _unlink_r(struct _reent *reent, const char *path);
int _unlink_r(struct _reent *reent, const char *path)
{ UNUSED_PARAM(reent); return _unlink(path);}
_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len);
_ssize_t _write_r(struct _reent *reent, int file, const void *ptr, size_t len)
{ UNUSED_PARAM(reent); return _write(file, ptr, len);}
/* FIXME: TDK added dummy functions. Need to implement. */
int _isatty(int fd);
int _isatty(int fd)
{
UNUSED_PARAM(fd);
return -1;
}
int _swistat(int fd, struct stat *st);
int _swistat(int fd, struct stat *st)
{
UNUSED_PARAM(fd);
UNUSED_PARAM(st);
return -1;
}
/* Return a clock that ticks at 100Hz. */
clock_t _clock(void);
clock_t _clock(void)
{
clock_t timeval=0;
return timeval;
}
int _swiclose(int fh);
int _swiclose(int fh)
{
UNUSED_PARAM(fh);
return -1;
}
int _swiopen(const char *path, int flags);
int _swiopen(const char *path, int flags)
{
UNUSED_PARAM(path);
UNUSED_PARAM(flags);
return -1;
}
int _swiwrite(int fh, char *ptr, int len);
int _swiwrite(int fh, char *ptr, int len)
{
UNUSED_PARAM(fh);
UNUSED_PARAM(ptr);
UNUSED_PARAM(len);
return -1;
}
int _swilseek(int fd, int ptr, int dir);
int _swilseek(int fd, int ptr, int dir)
{
UNUSED_PARAM(fd);
UNUSED_PARAM(ptr);
UNUSED_PARAM(dir);
return -1;
}
int _swiread(int fh, char *ptr, int len);
int _swiread(int fh, char *ptr, int len)
{
UNUSED_PARAM(fh);
UNUSED_PARAM(ptr);
UNUSED_PARAM(len);
return -1;
}
void initialise_monitor_handles(void);
void initialise_monitor_handles(void)
{
}
// ******************************************************************
// QtRvSim emulator https://github.com/cvut/qtrvsim support filees
//
// qtrvsim_unistd.h - definition of the QtRvSim syscall numbers
//
// (C) Copyright 2019 - 2022 by Pavel Pisa
// e-mail: pisa@cmp.felk.cvut.cz
// homepage: http://cmp.felk.cvut.cz/~pisa
// license: any combination of GPL, LGPL, MPL or BSD licenses
//
// ******************************************************************
#ifndef QTRVSIM_UNISTD_H
#define QTRVSIM_UNISTD_H
// Linux kernel compatible system calls subset
#define __NR_exit 93 // void exit(int status)
#define __NR_read 63 // ssize_t read(int fd, void *buf, size_t count)
#define __NR_write 64 // ssize_t write(int fd, const void *buf, size_t count)
#define __NR_close 57 // int close(int fd)
#define __NR_openat 56 // int openat(int fd, const char *pathname, int flags, mode_t mode)
// use fd = -100 for normal open behaviour. Full openat not supported.
#define __NR_brk 214 // void * brk(void *addr)
#define __NR_ftruncate64 46 // int ftruncate64(int fd, off_t length)
#define __NR_readv 65 // ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
#define __NR_writev 66 // ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
#endif /*QTRVSIM_UNISTD_H*/
*.o
*.srec
depend
branchpred-1
ARCH=riscv64-unknown-elf
#ARCH=riscv64-linux-gnu
SOURCES = branchpred-1.S
TARGET_EXE = branchpred-1
SOURCES += branchpred-1.S
LOADLIBES += -lc
CC=$(ARCH)-gcc
CXX=$(ARCH)-g++
AS=$(ARCH)-as
LD=$(ARCH)-ld
OBJCOPY=$(ARCH)-objcopy
ARCHFLAGS += -mabi=ilp32
ARCHFLAGS += -march=rv32im
ARCHFLAGS += -fno-lto
#ARCHFLAGS += -mabi=lp64
#ARCHFLAGS += -march=rv64imac
CFLAGS += -ggdb -Os -Wall
CXXFLAGS+= -ggdb -Os -Wall
AFLAGS += -ggdb
LDFLAGS += -ggdb
LDFLAGS += -nostartfiles
LDFLAGS += -nostdlib
LDFLAGS += -static
#LDFLAGS += -specs=/opt/musl/riscv64-linux-gnu/lib/musl-gcc.specs
LOADLIBES += -lgcc
CFLAGS += $(ARCHFLAGS)
CXXFLAGS+= $(ARCHFLAGS)
AFLAGS += $(ARCHFLAGS)
LDFLAGS += $(ARCHFLAGS)
OBJECTS += $(filter %.o,$(SOURCES:%.S=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o))
all : default
.PHONY : default clean dep all run_test
%.o:%.S
$(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $@
%.o:%.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
%.o:%.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
%.s:%.c
$(CC) $(CFLAGS) $(CPPFLAGS) -S $< -o $@
default : $(TARGET_EXE)
#default : run_test
$(TARGET_EXE) : $(OBJECTS)
$(CC) $(LDFLAGS) $^ $(LOADLIBES) -o $@
dep: depend
depend: $(SOURCES) $(glob *.h)
echo '# autogenerated dependencies' > depend
ifneq ($(filter %.S,$(SOURCES)),)
$(CC) -D__ASSEMBLY__ $(AFLAGS) -w -E -M $(filter %.S,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.c,$(SOURCES)),)
$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.cpp,$(SOURCES)),)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \
>> depend
endif
clean:
rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) depend
run_test: $(TARGET_EXE)
qtrvsim_cli --pipelined \
--dump-cycles $< \
--serout serial_port.out
# --serin serial_port.in \
-include depend
.globl _start
# i = s0, j = s1, c = s2, t0 = outer loop limits, t1 = inner loop limit, t3 - auxiliary variable
# c = 0; for ( i = 0; i < 4; i++) for ( j = 0; i < 5; j++) c++;
# c, i, j = 0; do { do { c++ } while(++j < 5) } while(i < 4);
_start:
addi s2, zero, 0 # c = 0; total loop count
addi t0, zero, 4 # t0 = 4; outer loop limit
addi t1, zero, 5 # t1 = 5; inner loop limit
addi s0, zero, 0 # i = 0; outer loop inc
L1:
addi s1, zero, 0 # j = 0; inner loop inc
L2:
addi s2, s2, 1 # c++;
addi s1, s1, 1 # j++;
slt t3, s1, t1 # t3 = (s1 < t1) ? 1 : 0;
bne t3, zero, L2
addi s0, s0, 1 # i++;
slt t3, s0, t0 # t3 = (s0 < t0) ? 1 : 0;
bne t3, zero, L1
ebreak