;-*-Lisp-*- (in-package goal) ;; name: gcommon.gc ;; name in dgo: gcommon ;; dgos: KERNEL ;; gcommon is the first file compiled and loaded. ;; it's expected that this function will mostly be hand-decompiled ;; The "identity" returns its input unchanged. It uses the special GOAL "object" ;; type, which can basically be anything, so this will work on integers, floats, ;; strings, structures, arrays, etc. The only things which doesn't work with "object" ;; is a 128-bit integer. The upper 64-bits of the integer will usually be lost. (defun identity ((x object)) ;; there is an optional "docstring" that can go at the beginning of a function "Function which returns its input. The first function of the game!" ;; the last thing in the function body is the return value. This is like "return x;" in C ;; the return type of the function is figured out automatically by the compiler ;; you don't have to specify it manually. x ) (defun 1/ ((x float)) "Reciprocal floating point" ;; this function computes 1.0 / x. GOAL allows strange function names like "1/". ;; Declaring this an inline function is like a C inline function, however code is ;; still generated so it can be used a function object. GOAL inline functions have type ;; checking, so they are preferable to macros when possible, to get better error messages. (declare (inline)) ;; the division form will pick the math type (float, int) based on the type of the first ;; argument. In this case, "1." is a floating point constant, so this becomes a floating point division. (/ 1. x) ) (defun + ((x int) (y int)) "Compute the sum of two integers" ;; this wraps the compiler's built-in handling of "add two integers" in a GOAL function. ;; now "+" can be used as a function object, but is limited to adding two integers when used like this. ;; The compiler is smart enough to not use this function unless "+" is being used as a function object. ;; ex: (+ a b c), (+ a b) ; won't use this function, uses built-in addition ;; (set-combination-function! my-thing +) ; + becomes a function pointer in this case (+ x y) ) (defun - ((x int) (y int)) "Compute the difference of two integers" (- x y) ) (defun * ((x int) (y int)) "Compute the product of two integers" ;; TODO - verify that this matches the PS2 exactly. ;; Uses mult (three operand form) in MIPS (* x y) ) (defun / ((x int) (y int)) "Compute the quotient of two integers" ;; TODO - verify this matches the PS2 exactly (/ x y) ) ;; todo ash ;; todo mod ;; todo rem (defun abs ((a int)) "Take the absolute value of an integer" ;; short function, good candidate for inlining (declare (inline)) ;; The original implementation was inline assembly, to take advantage of branch delay slots: ;; (or v0 a0 r0) ;; move input to output unchanged, for positive case ;; (bltzl v0 end) ;; if negative, execute the branch delay slot below... ;; (dsubu v0 r0 v0) ;; negate ;; (label end) (if (> a 0) ;; condition is "a > 0" a ;; true case, return a (- a) ;; false case, return -a. (- a) is like (- 0 a) ) ) (defun min ((a integer) (b integer)) "Compute minimum." ;; The original implementation was inline assembly, to take advantage of branch delay slots: ;; (or v0 a0 r0) ;; move first arg to output (case of second arg being min) ;; (or v1 a1 r0) ;; move second arg to v1 (likely strange coloring) ;; (slt a0 v0 v1) ;; compare args ;; (movz v0 v1 a0) ;; conditional move the second arg to v0 if it's the minimum (declare (inline)) (if (> a b) b a) ) (defun max ((a integer) (b integer)) "Compute maximum." (declare (inline)) (if (> a b) a b) ) ;; todo logior ;; todo lognor ;; todo logxor ;; todo lognot (defun false-func () "Return false" ;; In GOAL, #f is false. It's a symbol. Each symbol exists as an object, and each symbol has a value ;; The value of the false symbol #f is the false symbol #f. ;; To get the symbol, instead of its value, we use quote. Writing 'x is equivalent to (quote x) '#f ) (defun true-func () "Return true" ;; GOAL consideres anything that's not #f to be true. But there's also an explicit true symbol. '#t ) ;; The C Kernel implements the format function and creates a trampoline function in the GOAL heap which jumps to ;; format. (In OpenGOAL, there's actually two trampoline functions, to make the 8 arguments all work.) ;; For some reason, the C Kernel names this trampoline function _format. We need to set the value of format ;; _format in order for format to work. (define format _format) ;; todo bfloat ;; todo pinrt bfloat