Skip to content

Commit

Permalink
[RISC-V] Preliminary port of the riscv64 architecture
Browse files Browse the repository at this point in the history
  • Loading branch information
cyring committed Feb 22, 2025
1 parent cb9fc92 commit d281660
Show file tree
Hide file tree
Showing 25 changed files with 52,610 additions and 0 deletions.
845 changes: 845 additions & 0 deletions riscv64/bitasm.h

Large diffs are not rendered by default.

409 changes: 409 additions & 0 deletions riscv64/corefreq-api.h

Large diffs are not rendered by default.

219 changes: 219 additions & 0 deletions riscv64/corefreq-cli-extra.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/*
* CoreFreq (C) 2015-2025 CYRIL COURTIAT
* Contributors: Andrew Gurinovich ; CyrIng
* Licenses: GPL2
*
* Some ideas taken from https://github.com/cesanta/frozen/
* under Apache 2.0 license
*/

#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>

#include "corefreq-cli-extra.h"

#define UNUSED(expr) do { (void)(expr); } while (0)

/* --[ JSON toolkit ]-- */
struct json_state;

enum JSON_STATE {
DEFAULT, IN_ARRAY, IN_ARRAY2, IN_OBJECT, IN_OBJECT2
};

int json_writer_stdout(struct json_state * state, const char *str, size_t len)
{
UNUSED(state);
return fwrite(str, len, 1, stdout);
}

size_t get_utf8_char_len(unsigned char ch)
{
if ((ch & 0x80) == 0)
return 1;
switch (ch & 0xf0) {
case 0xf0:
return 4;
case 0xe0:
return 3;
default:
return 2;
}
}

/* This routine does NOT handle unicode finely - everything above 0x7f should
* be \u0000 encoded, but this requires us to be utf8 capable. Check the
* following tiny libraries(for future improvement):
* https://github.com/git/git/blob/master/utf8.c
* https://github.com/JeffBezanson/cutef8/blob/master/utf8.c
* https://github.com/sheredom/utf8.h
* https://github.com/JuliaStrings/utf8proc
*/

int json_escape(struct json_state *state, const char *p, size_t len)
{
size_t i, cl;
const char *hex_digits = "0123456789abcdef";
const char *specials = "btnvfr";
int n = 0;

for (i = 0; i < len; i++) {
unsigned char ch = ((unsigned char *) p)[i];
if (ch == '"' || ch == '\\') {
n += state->write(state, "\\", 1);
n += state->write(state, p + i, 1);
} else if (ch >= '\b' && ch <= '\r') {
n += state->write(state, "\\", 1);
n += state->write(state, &specials[ch - '\b'], 1);
} else if (isprint(ch)) {
n += state->write(state, p + i, 1);
} else if ((cl = get_utf8_char_len(ch)) == 1) {
n += state->write(state, "\\u00", 4);
n += state->write(state, &hex_digits[(ch >> 4) % 0xf], 1);
n += state->write(state, &hex_digits[ch % 0xf], 1);
} else {
n += state->write(state, p + i, cl);
i += cl - 1;
}
}
return n;
}

void json_start_object(struct json_state *state)
{
assert(state->depth < JSON_MAX_DEPTH);
/* TODO: assert(state->nested_state[state->depth] != IN_OBJECT); */
if (state->nested_state[state->depth] == IN_ARRAY2 ) {
state->write(state, ", {", 3);
} else {
state->write(state, "{", 1);
}
if (state->nested_state[state->depth] == IN_ARRAY) {
state->nested_state[state->depth] = IN_ARRAY2;
}
if (state->nested_state[state->depth] == IN_OBJECT) {
state->nested_state[state->depth] = IN_OBJECT2;
}
state->nested_state[++state->depth] = IN_OBJECT;
}

void json_end_object(struct json_state *state)
{
assert(state->depth >= 0);
assert(state->nested_state[state->depth] == \
IN_OBJECT || state->nested_state[state->depth] == IN_OBJECT2);

state->write(state, "}", 1);
state->nested_state[state->depth--] = DEFAULT;
}

void json_start_arr(struct json_state *state)
{
assert(state->depth < JSON_MAX_DEPTH);

if (state->nested_state[state->depth] == IN_ARRAY2) {
state->write(state, ", [", 3);
} else {
state->write(state, "[", 1);
}
if (state->nested_state[state->depth] == IN_ARRAY) {
state->nested_state[state->depth] = IN_ARRAY2;
}
if (state->nested_state[state->depth] == IN_OBJECT) {
state->nested_state[state->depth] = IN_OBJECT2;
}
state->nested_state[++state->depth] = IN_ARRAY;
}

void json_end_arr(struct json_state *state)
{
assert(state->depth >= 0);
assert(state->nested_state[state->depth] == \
IN_ARRAY || state->nested_state[state->depth] == IN_ARRAY2);

state->write(state, "]", 1);
state->nested_state[state->depth--] = DEFAULT;
}

void json_key(struct json_state *state, char * key)
{
assert(state->nested_state[state->depth] == \
IN_OBJECT || state->nested_state[state->depth] == IN_OBJECT2);

if (state->nested_state[state->depth] == IN_OBJECT2) {
state->write(state, ", ", 1);
}
state->write(state, "\"", 1);
json_escape(state, key, strlen(key));
state->write(state, "\":", 2);
}

void json_string(struct json_state *state, char * value)
{
assert(state->nested_state[state->depth] != DEFAULT);

if (state->nested_state[state->depth] == IN_ARRAY2) {
state->write(state, ", ", 2);
}
if (state->nested_state[state->depth] == IN_ARRAY) {
state->nested_state[state->depth] = IN_ARRAY2;
}
if (state->nested_state[state->depth] == IN_OBJECT) {
state->nested_state[state->depth] = IN_OBJECT2;
}
state->write(state, "\"", 1);
json_escape(state, value, strlen(value));
state->write(state, "\"", 1);
}

void json_literal(struct json_state *state, char * format, ...)
{
assert(state->nested_state[state->depth] != DEFAULT);

if (state->nested_state[state->depth] == IN_ARRAY2) {
state->write(state, ", ", 2);
}
if (state->nested_state[state->depth] == IN_ARRAY) {
state->nested_state[state->depth] = IN_ARRAY2;
}
if (state->nested_state[state->depth] == IN_OBJECT) {
state->nested_state[state->depth] = IN_OBJECT2;
}
va_list args;
va_start(args, format);
char buf[JSON_MAX_VALUE];
const int rc = vsprintf(buf, format, args);
const size_t bufsz = rc > 0 ? (size_t) rc : 0;
state->write(state, buf, bufsz);
va_end(args);
}

/* --[ UTF toolkit ]-- */

void ISO_8859_To_Unicode(unsigned char *pIn, unsigned char *pOut)
{
while ( (*pIn) != '\0' ) {
if ( (*pIn) > 0x7f ) {
switch ( (*pIn) ) {
case 0xc0 ... 0xff: /* To UTF-8 Ctrl:C3 */
(*pOut) = (*pIn) ^ 0x40;
break;
case 0xa0 ... 0xbf: /* To UTF-8 Ctrl:C2 */
(*pOut) = (*pIn) ^ 0x60;
break;
default:
(*pOut) = 0x20;
break;
}
} else {
(*pOut) = (*pIn);
}
pIn++;
pOut++;
}
(*pOut) = '\0';
}
30 changes: 30 additions & 0 deletions riscv64/corefreq-cli-extra.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* CoreFreq (C) 2015-2025 CYRIL COURTIAT
* Contributors: Andrew Gurinovich ; CyrIng
* Licenses: GPL2
*
* Some ideas taken from github.com/cesanta/frozen
* under Apache 2.0 license
*/

#define JSON_MAX_DEPTH 32
#define JSON_MAX_VALUE 4096

struct json_state {
int (*write)(struct json_state* state, const char *str, size_t len);
unsigned char nested_state[JSON_MAX_DEPTH];
unsigned char depth;
};

extern int json_writer_stdout( struct json_state * state,
const char *str,
size_t len) ;
extern void json_start_object(struct json_state *state) ;
extern void json_end_object(struct json_state *state) ;
extern void json_start_arr(struct json_state *state) ;
extern void json_end_arr(struct json_state *state) ;
extern void json_key(struct json_state *state, char * key) ;
extern void json_string(struct json_state *state, char * value) ;
extern void json_literal(struct json_state *state, char * format, ...) ;

extern void ISO_8859_To_Unicode(unsigned char*, unsigned char*) ;
Loading

0 comments on commit d281660

Please sign in to comment.