head 1.14; access; symbols bg2_23:1.14 bg2_22:1.14 bg2_21:1.14 bg2_20:1.14 bg2_16:1.13 bg2_15:1.13 bg2_12:1.13 bg2_07:1.13 isorc2008_submission:1.11 handbook_alpha_edition:1.11 jtres2007_submission:1.11 bg1_07:1.9 bg1_06:1.9 bg1_05:1.9 TAL_101:1.8 TAL_100:1.8 jtres_submission:1.8 wises06_submission:1.8 lctes2006_submission:1.8 rtgc_isorc2006:1.7.0.4 isorc2006:1.7.0.2 rtgc_paper:1.7 bg1_00:1.7 nohandle:1.7 thesis:1.4; locks; strict; comment @# @; 1.14 date 2008.07.03.13.06.25; author jeuneS2; state Exp; branches; next 1.13; commitid f77486cce9b4567; 1.13 date 2008.02.23.23.41.05; author martin; state Exp; branches; next 1.12; commitid 135e47c0af0e4567; 1.12 date 2008.02.05.16.52.53; author jeuneS2; state Exp; branches; next 1.11; commitid 7b4b47a894494567; 1.11 date 2007.04.12.00.46.18; author martin; state Exp; branches; next 1.10; commitid 5f15461d81564567; 1.10 date 2007.04.11.23.52.53; author martin; state Exp; branches; next 1.9; commitid 4286461d74d04567; 1.9 date 2006.11.04.23.28.01; author martin; state Exp; branches; next 1.8; commitid 23e6454d21f84567; 1.8 date 2006.01.12.18.46.42; author martin; state Exp; branches; next 1.7; commitid 77af43c6a4054567; 1.7 date 2005.06.13.18.42.30; author martin; state Exp; branches; next 1.6; commitid 2ea742add3724567; 1.6 date 2005.05.12.16.42.29; author martin; state Exp; branches; next 1.5; commitid 2819428387704567; 1.5 date 2005.02.05.22.15.08; author martin; state Exp; branches; next 1.4; 1.4 date 2005.02.05.16.57.46; author martin; state Exp; branches; next 1.3; 1.3 date 2004.09.16.20.00.15; author martin; state Exp; branches; next 1.2; 1.2 date 2004.09.13.14.38.12; author martin; state Exp; branches; next 1.1; 1.1 date 2004.09.10.07.58.52; author martin; state Exp; branches; next ; desc @@ 1.14 log @A bunch of small fixes (error handling, division, stringification of integers). @ text @// // This file is a part of JOP, the Java Optimized Processor // // Copyright (C) 2001-2008, Martin Schoeberl (martin@@jopdesign.com) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // // call.inc // // include file for invoke and return functions // // 2004-08-19 extracted from jvm.asm // // see changlog in jvm.asm // // // local vars for tmp storage // old_mp ? old_vp ? old_jpc ? old_cp ? // for now save it on stack start ? end ? args ? varcnt ? invokespecial: // is it really equivalent ????? (not really) // there is an object ref on stack (but arg counts for it) // is called for privat methods AND !!! invokestatic: // mp = readMem(cp+idx); ldm cp opd nop opd ld_opd_16u add invoke_main: // jmp with pointer to pointer to mp on TOS stmra // read 'real' mp wait wait ldmrd // read ext. mem jopsys_invoke: // called from Startup.boot() with pointer to main() method struct invoke: // jmp with mp on TOS (pointer to method struct) ldi 1 // nop // mp is != 0 bnz invoke_vpsave ldvp // save vp stm old_vp // in branch slots invokeinterface: ldm cp opd nop opd ld_opd_16u add opd stmra opd // read constant wait wait ldmrd // off on TOS dup ldi 255 and stm a // arg count (without objectref) ldi 8 ushr stm b // offset in method table ldsp // one increment but still one to low ('real' sp is sp+2 because of registers) ldi 1 // 'real' sp add ldm a sub star // address of objectref nop ldmi // read objectref // objectref is now on TOS dup // null pointer check nop bz null_pointer ldvp // save vp in branch slot stm old_vp ldi 1 // at address ref+1 (in the handle) is the pointer to method table add stmra // read pointer to method table wait wait ldmrd // vt on TOS ldi 1 // pointer to interface table sub // befor method table stmra // read interface table address wait wait ldmrd // it on TOS ldm b add // add offset stmra // read method pointer wait // from interface table wait ldmrd // mp on TOS ldi 1 // nop // mp is != 0 bnz invoke_vpsave nop nop invokesuper: // this was invokespecial, replaced in JOPizer when calling super methods ldm cp opd nop opd ld_opd_16u add stmra // read constant wait wait ldmrd // read ext. mem dup ldi 255 and stm a // arg count (without objectref) ldi 8 ushr stm b // offset in method table ldsp // one increment but still one to low ('real' sp is sp+2 because of registers) ldi 1 // 'real' sp add ldm a sub star // address of objectref nop ldmi // read objectref // objectref is now on TOS dup // null pointer check nop bz null_pointer ldvp // save vp in branch slot stm old_vp ldi 1 // at address ref+1 (in the handle) is the pointer to method table add stmra // read pointer to method table of this wait wait ldmrd // read ext. mem ldi -2 // superclass pointer is at vt-2 add stmra // read pointer to superclass wait wait ldmrd // read ext. mem ldi 5 // "super" method table is at superclass+5 add ldi 1 // nop // mp is != 0 bnz invoke_addoffset nop nop nop // to keep offtbl.vhd short enough.... invokevirtual: ldm cp opd nop opd ld_opd_16u add stmra // read constant wait wait ldmrd // read ext. mem dup ldi 255 and stm a // arg count (without objectref) ldi 8 ushr stm b // offset in method table ldsp // one increment but still one to low ('real' sp is sp+2 because of registers) ldi 1 // 'real' sp add ldm a sub star // address of objectref nop ldmi // read objectref // objectref is now on TOS dup // null pointer check nop bz null_pointer ldvp // save vp in branch slot stm old_vp ldi 1 // at address ref+1 (in the handle) is the pointer to method table add stmra // read pointer to method table wait wait ldmrd // read ext. mem invoke_addoffset: ldm b add // add offset invoke_vpsave: // vp is allready saved in old_vp // used for invokestatic and invokevirtual //******************************* // test for oohw change // invoke would be 102, invokestatic would be 75 // we use 89 as arithmetic mean // ldi 16 // 17*5+2+2=102 //dlyl: // dup // nop // bnz dlyl // ldi -1 // decrement in branch slot // add // pop // remove counter // nop // nop //******************************* // mp is on TOS // we will not read mem[mp] now, // this is done in load_bc dup ldi 1 add stmra // read cp+arrg/locals count ldm mp stm old_mp stm mp wait wait ldmrd // cp... // cp = readMem(mp+1); // int locals = (cp>>>5) & 0x01f; // int args = cp & 0x01f; // cp >>>= 10; // get 'old' (= current) bc start address // and store relative jpc in stack frame ldjpc ldbcstart sub // relative pc stm old_jpc // TODO: ldjpc and subtraction could be moved down // get method start address and length ldm mp stmra ldm cp stm old_cp wait wait ldmrd // read ext. mem // int len = start & 0x03ff; // start >>>= 10; // start bytecode load.... stbcrd dup ldi 31 and stm args ldi 5 ushr dup ldi 31 and stm varcnt ldi 5 ushr stm cp old_sp ? real_sp ? // // tos and tos-1 are allready written back to memory // // int old_sp = sp-args; // vp = old_sp+1; // sp += varcnt; ldsp // one increment but still one to low ('real' sp is sp+2 because of registers) ldi 1 // 'real' sp da sp auf rd adr zeigt add dup ldm args sub stm old_sp ldm old_sp ldi 1 add stvp // sp still on TOS ldm varcnt // 'real' varcnt (=locals-args) add nop // written in adr/read stage! stsp pop // flush reg., sp reg is sp-2 again pop // could really be optimized :-( // stack[++sp] = old_sp; // stack[++sp] = cache.corrPc(pc); // in VarBlockCache: // save pc relative to start address of the method // return (pc - currentBlock*blockSize) & mask; // stack[++sp] = old_vp; // stack[++sp] = old_cp; // stack[++sp] = old_mp; // // pc = cache.invoke(start, len); // in VarBlockCache: // test or load cache, return start address (block number * size) // int off = testCache(start, len); // return off; ldm old_sp ldm old_jpc // without cache load jpc here // ldi 0 // stjpc // bc start address is a 'few' cycles after stbcrd available ldbcstart // for future cache stjpc ldm old_vp ldm old_cp ldm old_mp // wait on bytecode load from memory system wait wait nop nxt // end load_bc // // thats the pipeline delay from stjpc - jpc - // rdaddress - jpaddr - pc! // // could be simpler if a different command to store // write address for jbc (or use DMA in mem.vhd!) // // stjpc // nop // nop // nop // nop nxt // areturn: freturn: ireturn: stm a // store return value dup // mp is on tos stmra stm mp stm cp stvp wait // wait for mem(mp) wait ldmrd // read ext. mem stbcrd // start bytecode load // stjpc stm old_jpc // save realtive pc nop // written in adr/read stage! stsp // last is new sp pop // flash tos, tos-1 (registers) pop // sp must be two lower, points to rd adr ldbcstart // start block of method ldm old_jpc // plus relative jpc add stjpc ldm a // load return value // wait on bytecode load from memory system wait wait nop nxt dreturn: lreturn: stm a // store return value stm b dup // mp is on tos stmra stm mp stm cp stvp wait // wait for mem(mp) wait ldmrd // read ext. mem stbcrd // start bytecode load // stjpc stm old_jpc // save realtive pc nop // written in adr/read stage! stsp // last is new sp pop // flash tos, tos-1 (registers) pop // sp must be two lower, points to rd adr ldbcstart // start block of method ldm old_jpc // plus relative jpc add stjpc ldm b ldm a // load return value // wait on bytecode load from memory system wait wait nop nxt return: // mp = stack[sp--]; // cp = stack[sp--]; // vp = stack[sp--]; // pc = stack[sp--]; // sp = stack[sp--]; // // int start = readMem(mp); // int len = start & 0x03ff; // start >>>= 10; // pc = cache.ret(start, len, pc); // in VarBlockCache: // int off = testCache(start, len); // return (off+pc) & mask; dup // mp is on tos stmra stm mp stm cp stvp wait // wait for mem(mp) wait ldmrd // read ext. mem stbcrd // start bytecode load // stjpc stm old_jpc // save realtive pc nop // written in adr/read stage! stsp // last is new sp ldbcstart // start block of method ldm old_jpc // plus relative jpc add stjpc pop // flash tos, tos-1 (registers) pop // sp must be two lower, points to rd adr // wait on bytecode load from memory system wait wait nop nxt // end load_bc @ 1.13 log @JOP goes GPL @ text @d45 1 a45 1 invokespecial: // is it really equivilant ????? (not really) d94 2 a95 2 ldsp // one increment but still one to low ('real' sp is sp+2 because of registers) ldi 1 // 'real' sp da sp auf rd adr zeigt d100 3 a102 5 ldvp stm old_vp stvp // address in vp nop // ??? ld0 // read objectref a105 3 nop // could be interleaved with bz null_pointer // following code nop d107 3 d138 1 a138 1 invokesuper: // this was invokespecial, replaced in JOPizer when calling super methods d152 1 a152 1 stm a // arg count (without objectref) d155 1 a155 1 stm b // offset in method table d158 1 a158 1 ldi 1 // 'real' sp da sp auf rd adr zeigt d163 3 a165 5 ldvp stm old_vp stvp // address in vp nop // ??? ld0 // read objectref d168 5 a172 5 dup // null pointer check nop // could be interleaved with bz null_pointer // following code nop nop d174 1 a174 1 ldi 1 // at address ref+1 (in the handle) is the pointer to method table d182 2 a183 2 ldi -2 // superclass pointer is at vt-2 add d190 2 a191 2 ldi 5 // "super" method table is at superclass+5 add d193 1 a193 1 ldi 1 d221 2 a222 2 ldsp // one increment but still one to low ('real' sp is sp+2 because of registers) ldi 1 // 'real' sp da sp auf rd adr zeigt d227 3 a229 5 ldvp stm old_vp stvp // address in vp nop // ??? ld0 // read objectref a232 3 nop // could be interleaved with bz null_pointer // following code nop d234 3 @ 1.12 log @Introduced invokesuper. @ text @d2 19 @ 1.11 log @OO HW tests in comments @ text @d121 56 d178 5 d184 1 d233 1 @ 1.10 log @OO HW tests in comments @ text @d181 3 a183 1 // ldi 19 // 20*5+2=102 d191 2 @ 1.9 log @Moved mtab pointer and array length from the object/array to the handle @ text @d178 13 @ 1.8 log @HW/SW exceptions, additional ar for local memory addressing, sp and vp are effective 7 bits now (MSB fixed) @ text @a56 11 // int idx = readOpd16u(); // readOpd16u(); // read historical argument count and 0 // int off = readMem(cp+idx); // index in interface table // int args = off & 0xff; // this is args count without obj-ref // off >>>= 8; // int ref = stack[sp-args]; // int vt = readMem(ref-1); // pointer to virtual table in obj-1 // int it = readMem(vt-1); // pointer to interface table one befor vt // int mp = readMem(it+off); // invoke(mp); d94 2 a95 9 #ifdef HANDLE stmra // read handle indirection wait // for the GC wait ldmrd #endif ldi 1 // at address ref-1 is pointer to method table sub a125 8 // int idx = readOpd16u(); // int off = readMem(cp+idx); // index in vt and arg count (-1) // int args = off & 0xff; // off >>>= 8; // int ref = stack[sp-args]; // int vt = readMem(ref-1); // invoke(vt+off); d163 2 a164 10 #ifdef HANDLE stmra // read handle indirection wait // for the GC wait ldmrd #endif ldi 1 // at address ref-1 is pointer to method table sub @ 1.7 log @Last version without object handles. @ text @a91 1 // could do the vp save in old_vp here @ 1.6 log @change mem32 to not generate a bsy on ram_cnt=2. remove nops from mem rd/wr in jvm.asm (jvm_call.inc). bsy is set onle cycle earlier with 'wr'. @ text @a9 1 // TODO d103 10 d187 11 @ 1.5 log @histroy list in comment moved to jvm.asm @ text @a40 1 nop a74 1 nop a106 1 nop a113 1 nop d121 1 a121 2 nop // from interface table wait a149 1 nop a181 1 nop @ 1.4 log @Thesis version @ text @d7 2 a8 2 // 2004-09-16 new bc read hardware // 2005-01-10 changes for bytecode cache @ 1.3 log @bytecode load in hardware (mem32.vhd). @ text @d7 2 d17 1 d220 10 a229 1 // start bytecode load.... d242 2 a243 1 stbcrd // start bytecode load d293 4 a296 1 // stack[++sp] = pc; d300 6 a305 1 d308 1 a308 1 ldjpc d310 5 a314 2 ldi 0 stjpc a321 7 // TODO: use ldbcstart in jpc save and in return for correct cache handling // ldbcstart // for future cache // stjpc // nop // nop // nop d352 2 a353 1 stjpc d359 6 d366 2 a367 1 wait // wait on bytecode load from memory system d384 2 a385 1 stjpc d391 6 d399 2 a400 1 wait // wait on bytecode load from memory system d405 16 d430 2 a431 1 stjpc d435 6 d443 2 a444 1 wait // wait on bytecode load from memory system d447 1 a447 1 @ 1.2 log @bytecode load in hardware. @ text @a206 2 ldm cp stm old_cp d217 16 a249 1 new_jpc ? d288 3 a294 23 ldi 0 stm new_jpc // // now load bc from external ram :-( // load_bc: ldm mp stmra ldi 0 stjpc wait wait ldmrd // read ext. mem /////////////////// hardware version //////////////////// stbcrd // start bytecode load ldm new_jpc stjpc a297 9 nop nop nxt // end load_bc /////////////////// hardware version //////////////////// // int len = start & 0x03ff; // start >>>= 10; dup ldi 10 ushr d299 6 a304 51 dup stmra // first bytecode word stm start ldi 1023 and // mask len ldm start add stm end // // this fetch loop takes about 66% in Mast.java! // => to be optimized (hw fetch, cach) // 2003-08-14 changed from 29 cycles to 17 cycles per word // ldbc_rd_l: wait wait ldmrd // read ext. mem ldm start // addr inc. ldi 1 add stm start ldm start stmra // start next read // only one 32 bit store // jbc automaitcally writes 4 bytes // this takes 'some' time (about 5) cycles stbc // check loop ldm end // end address ldm start // start is address 'counter' xor nop bnz ldbc_rd_l nop nop ldm new_jpc stjpc // wait on last (unused) memory read. wait wait nop d325 3 a327 1 stm a // return value d331 5 d337 33 a369 11 stm new_jpc nop // written in adr/read stage! stsp // last is new sp pop // flash tos, tos-1 (registers) pop // sp must be two lower, points to rd adr ldm a ldi 1 nop bnz load_bc nop nop d372 2 d377 13 a390 10 stm new_jpc nop // written in adr/read stage! stsp // last is new sp pop // flash tos, tos-1 (registers) pop // sp must be two lower, points to rd adr ldi 1 nop bnz load_bc nop nop @ 1.1 log @resync of actual development. @ text @d286 2 d296 13 @