abstractaccelerator/demo/helloworld/hello_world.c

163 lines
3.5 KiB
C

int STACK = 0x8000;
#define STDOUT 0xd0580000
__asm(".section .text_init, \"ax\"");
__asm(".global _start");
__asm("_start:");
// Enable Caches in MRAC
__asm("li t0, 0x5f555555");
__asm("csrw 0x7c0, t0");
// Set stack pointer.
__asm("la sp, STACK");
__asm("call main");
// Write 0xff to STDOUT for TB to termiate test.
__asm(".global _finish");
__asm("_finish:");
__asm("li t0, 0xd0580000");
__asm("addi t1, zero, 0xff");
__asm("sb t1, 0(t0)");
__asm("beq x0, x0, _finish");
__asm(".rept 10");
__asm("nop");
__asm(".endr");
__asm(".section .text");
#include <stdarg.h>
static int whisperPutc(char c) {
*(volatile char*)(STDOUT) = c;
return c;
}
static int whisperPuts(const char* s) {
while (*s) whisperPutc(*s++);
return 1;
}
static int whisperPrintDecimal(int value) {
char buffer[20];
int charCount = 0;
unsigned neg = value < 0;
if (neg) {
value = -value;
whisperPutc('-');
}
do {
char c = '0' + (value % 10);
value = value / 10;
buffer[charCount++] = c;
} while (value);
char* p = buffer + charCount - 1;
for (unsigned i = 0; i < charCount; ++i) whisperPutc(*p--);
if (neg) charCount++;
return charCount;
}
static int whisperPrintInt(int value, int base) {
if (base == 10) return whisperPrintDecimal(value);
char buffer[20];
int charCount = 0;
unsigned uu = value;
if (base == 8) {
do {
char c = '0' + (uu & 7);
buffer[charCount++] = c;
uu >>= 3;
} while (uu);
} else if (base == 16) {
do {
int digit = uu & 0xf;
char c = digit < 10 ? '0' + digit : 'a' + digit - 10;
buffer[charCount++] = c;
uu >>= 4;
} while (uu);
} else
return -1;
char* p = buffer + charCount - 1;
for (unsigned i = 0; i < charCount; ++i) whisperPutc(*p--);
return charCount;
}
int whisperPrintfImpl(const char* format, va_list ap) {
int count = 0; // Printed character count
for (const char* fp = format; *fp; fp++) {
if (*fp != '%') {
whisperPutc(*fp);
++count;
continue;
}
++fp; // Skip %
if (*fp == 0) break;
if (*fp == '%') {
whisperPutc('%');
continue;
}
if (*fp == '-') {
fp++; // Pad right not yet implemented.
}
while (*fp == '0') {
fp++; // Pad zero not yet implented.
}
if (*fp == '*') {
int width = va_arg(ap, int);
fp++; // Width not yet implemented.
} else {
while (*fp >= '0' && *fp <= '9') ++fp; // Width not yet implemented.
}
switch (*fp) {
case 'd':
count += whisperPrintDecimal(va_arg(ap, int));
break;
case 'u':
count += whisperPrintDecimal((unsigned)va_arg(ap, unsigned));
break;
case 'x':
case 'X':
count += whisperPrintInt(va_arg(ap, int), 16);
break;
case 'o':
count += whisperPrintInt(va_arg(ap, int), 8);
break;
case 'c':
whisperPutc(va_arg(ap, int));
++count;
break;
case 's':
count += whisperPuts(va_arg(ap, char*));
break;
}
}
return count;
}
int whisperPrintf(const char* format, ...) {
va_list ap;
va_start(ap, format);
int code = whisperPrintfImpl(format, ap);
va_end(ap);
return code;
}
int printf(const char* format, ...) {
va_list ap;
va_start(ap, format);
int code = whisperPrintfImpl(format, ap);
va_end(ap);
return code;
}
// #include <stdio.h>
int add(int a, int b) { return (a + b) * (a - b); }
int main() {
printf("Hello RISCV!\n");
int a = add(1, 23);
printf("a:%d\n", a);
return 0;
}