;;;-*- Mode: Lisp; Package: cl-user -*- (in-package :cl-user) (defparameter *assembler* '( #+avr #" // Assembler #if defined(CPU_ATmega1284P) #define CODE_ADDRESS 0x1bb00 #elif defined(CPU_AVR128DX48) #define CODE_ADDRESS 0x1be00 #endif object *call (int entry, int nargs, object *args, object *env) { #if defined(CODESIZE) (void) env; int param[4]; for (int i=0; iinteger; else param[i] = (uintptr_t)arg; args = cdr(args); } uint32_t address = (CODE_ADDRESS + entry)>>1; // Code addresses are word addresses on AVR int w = ((intfn_ptr_type)address)(param[0], param[1], param[2], param[3]); return number(w); #else return nil; #endif }"# #+arm #" // Assembler object *call (int entry, int nargs, object *args, object *env) { #if defined(CODESIZE) (void) env; int param[4]; for (int i=0; iinteger; else param[i] = (uintptr_t)arg; args = cdr(args); } int w = ((intfn_ptr_type)&MyCode[entry])(param[0], param[1], param[2], param[3]); return number(w); #else return nil; #endif }"# #+riscv #" // Assembler object *call (int entry, int nargs, object *args, object *env) { #if defined(CODESIZE) (void) env; int param[4]; for (int i=0; iinteger; else param[i] = (uintptr_t)arg; args = cdr(args); } asm("fence.i"); int w = ((intfn_ptr_type)&MyCode[entry])(param[0], param[1], param[2], param[3]); return number(w); #else return nil; #endif }"# #+avr #" void putcode (object *arg, int origin, int pc) { #if defined(CODESIZE) int code = checkinteger(arg); uint8_t hi = (code>>8) & 0xff; uint8_t lo = code & 0xff; MyCode[origin+pc] = lo; // Little-endian MyCode[origin+pc+1] = hi; #if defined(assemblerlist) printhex2(pc>>8, pserial); printhex2(pc, pserial); pserial(' '); printhex2(lo, pserial); pserial(' '); printhex2(hi, pserial); pserial(' '); #endif #endif }"# #+(or arm riscv) #" void putcode (object *arg, int origin, int pc) { #if defined(CODESIZE) int code = checkinteger(arg); MyCode[origin+pc] = code & 0xff; MyCode[origin+pc+1] = (code>>8) & 0xff; #if defined(assemblerlist) printhex4(pc, pserial); printhex4(code, pserial); #endif #endif }"# #+avr #" int assemble (int pass, int origin, object *entries, object *env, object *pcpair) { int pc = 0; cdr(pcpair) = number(pc); while (entries != NULL) { object *arg = first(entries); if (symbolp(arg)) { if (pass == 2) { #if defined(assemblerlist) printhex2(pc>>8, pserial); printhex2(pc, pserial); indent(7, ' ', pserial); printobject(arg, pserial); pln(pserial); #endif } else { object *pair = findvalue(arg, env); cdr(pair) = number(pc); } } else { object *argval = eval(arg, env); if (listp(argval)) { object *arglist = argval; while (arglist != NULL) { if (pass == 2) { putcode(first(arglist), origin, pc); #if defined(assemblerlist) if (arglist == argval) superprint(arg, 0, pserial); pln(pserial); #endif } pc = pc + 2; cdr(pcpair) = number(pc); arglist = cdr(arglist); } } else if (integerp(argval)) { if (pass == 2) { putcode(argval, origin, pc); #if defined(assemblerlist) superprint(arg, 0, pserial); pln(pserial); #endif } pc = pc + 2; cdr(pcpair) = number(pc); } else error(PSTR("illegal entry"), arg); } entries = cdr(entries); } // Round up to multiple of 2 to give code size if (pc%2 != 0) pc = pc + 2 - pc%2; return pc; }"# #+(or arm riscv) #" int assemble (int pass, int origin, object *entries, object *env, object *pcpair) { int pc = 0; cdr(pcpair) = number(pc); while (entries != NULL) { object *arg = first(entries); if (symbolp(arg)) { if (pass == 2) { #if defined(assemblerlist) printhex4(pc, pserial); indent(5, ' ', pserial); printobject(arg, pserial); pln(pserial); #endif } else { object *pair = findvalue(arg, env); cdr(pair) = number(pc); } } else { object *argval = eval(arg, env); if (listp(argval)) { object *arglist = argval; while (arglist != NULL) { if (pass == 2) { putcode(first(arglist), origin, pc); #if defined(assemblerlist) if (arglist == argval) superprint(arg, 0, pserial); pln(pserial); #endif } pc = pc + 2; cdr(pcpair) = number(pc); arglist = cdr(arglist); } } else if (integerp(argval)) { if (pass == 2) { putcode(argval, origin, pc); #if defined(assemblerlist) superprint(arg, 0, pserial); pln(pserial); #endif } pc = pc + 2; cdr(pcpair) = number(pc); } else error(PSTR("illegal entry"), arg); } entries = cdr(entries); } // Round up to multiple of 4 to give code size if (pc%4 != 0) pc = pc + 4 - pc%4; return pc; }"#))