/* yasep/JScore/yasep_opcodes.js
created 2006-08-08 by whygee@f-cpu.org
2006-08-08
2006-08-16 : added vanity pretty-print
2006-09-02 : moved to vspsim/JScore/
2007-04-06 : some rework for the Queues and the conditions
2007-04-07 : allowing opcode aliases
2007-04-09 : moved decorate_opcode() from JSgui/decoration.js,
   moved the flags away from the forms field
2007-11-05 : rebranding to YASEP
2008-11-30 :
 * removed A0/D0
 * adding 16-bit computation functions
2009-07-19 : added NewAlias()
2009-07-28 : added Y

This file defines the general opcode table
(and the reverse tables) that help encoding and
decoding the YASEP instructions.

note : the opcodes themselves are generated in different files.

Dependency : yasep_forms.js for the declaration of Y
*/

/////////////////////////////// The core's registers: ///////////////////////////////
Y.registers_names=new Array(
  "R0","R1","R2","R3","R4",
  "NPC",
  "A0", "D0",
  "A1", "D1",
  "A2", "D2",
  "A3", "D3",
  "A4", "D4"
);

// the reverse table :
Y.names_registers=new Array;
for (var i=0; i<16; i++)
  Y.names_registers[Y.registers_names[i]]=i;

/////////////////////////////// The instruction object : ///////////////////////////////

Y.prefix=0; // declared and initialized here. Must not be touched later
// or the other instructions won't initialize correctly !!! (except for alignment)
Y.opcode_step=1<<5;

Y.opcode_table=new Array(); // contains all the important data
Y.table_opcode=new Array(); // reverse table for the above one
Y.opcode_aliases=new Array(); // List of aliases and their "real" names


// build both tables at once
Y.NewOpcode=function(name, action32, action16, forms, flags, description) {
  // the variable "prefix" must already exist
  if (Y.table_opcode[name]!=undefined) {
    document.write("<p>Warning ! "+name+" : opcode already defined</p>");
    return;
  }
  Y.table_opcode[name]={
    value: Y.prefix, // value of the alias
    forms: forms,  // the forms of the alias may be different from the base's forms.
    flags: flags,
    description: description};
  Y.opcode_table[Y.prefix]={
    name:name,
    action32:action32,
    action16:action16,
    forms:forms,
    flags:flags,
    description:description};
  Y.prefix+=Y.opcode_step; // increment inside the group
}

Y.NewAlias=function(name, aliasTo, forms, flags, description) {
  Y.NewOpcode(name, null, null, forms, flags, description);
  Y.opcode_aliases[name]=aliasTo;
  Y.prefix-=Y.opcode_step; // leave the counter unchanged so the real instruction can come after.
}

// build both tables at once
Y.NoOpcode=function() {
  Y.prefix+=Y.opcode_step; // increment inside the group
}

// pretty-print :

Y.decorate_opcode=function(opcode_value){
  return '<a class="opcode" href="'+prfx+'ISM/'+Y.opcode_table[opcode_value].name
   +'.html"  title="'+Y.opcode_table[opcode_value].description+'">'+Y.opcode_table[opcode_value].name+'</a>';
}
