/* file yasep/JScore/group_shl.js
This file is distributed under terms of the Affero GPL v3 license or later, see http://yasep.org
created 2005-06-11 by whygee@f-cpu.org
2007-04-11 : moved from vsp_eu.js to group_shl.js
2007-11-05 : rebranding to YASEP, use of IMM16_5LSB
2008-11-30 : 16-bit action
2009-05-26 : removed MUL
2009-07-19 : renamed WRITE_SRC2ifIMM to WRITE_SRC2ifIMM16
2009-07-28 : added Y
2009-07-29 : FORM_iR
2009-08-07 : s.result...
2009-08-09 : removed SWAPDEST
2014-02-06 : added SHLO, SHRO and BSWAP

This file implements the "SHL" (bit SHuffLer) Execution Unit

dependency : group_eu.js and all its parents

the big headache comes from the fact that dest_src must be the address of source2.
So if we want to write the dest last, the assembler must swap the fields
*/

Y.prefix=Y.GROUP_SHL;

var f=Y.FORM_RR | Y.FORM_IRR | Y.FORM_iR | Y.FORM_IR | Y.FORM_iRR | Y.FORM_RRR,
    g=Y.IMM16_5LSB | Y.IgnoreImmSign | Y.ALIAS_IRR;

Y.NewOpcode("SHR",
 function(s) {
   var t = s.si4 & 31;
   if (t==0)
     s.result = s.snd;
   else
     s.result = s.snd >>> t;
 },
 function(s) {
   var t = s.si4 & 15;
   if (t==0)
     s.result =  s.snd & F4;
   else
     s.result = (s.snd >>> t) & F4;
 },f,g,
 "SHift logic Right");

Y.NewOpcode("SHRO",
 function(s) {
   var t = s.si4 & 31;
   if (t==0)
     s.result |= s.snd;
   else
     s.result |= s.snd >>> t;
 },
 function(s) {
   var t = s.si4 & 15;
   if (t==0)
     s.result |=  s.snd & F4;
   else
     s.result |= (s.snd >>> t) & F4;
 },
    Y.FORM_IRR | Y.FORM_iRR | Y.FORM_RRR,
    Y.IMM16_5LSB | Y.IgnoreImmSign | Y.READ_DST |  Y.OPTIONAL,
 "SHift logic Right and OR");

Y.NewOpcode("SAR",
 function(s) { s.result =  s.snd >> (s.si4 & 31); },
 function(s) { s.result = (s.snd >> (s.si4 & 15)) & F4; }, f,g,
 "Shift Arithmetic Right");

Y.NewOpcode("SHL",
 function(s) { s.result =  s.snd << (s.si4 & 31); },
 function(s) { s.result = (s.snd << (s.si4 & 15)) & F4; }, f,g,
 "SHift logic Left");

Y.NewOpcode("SHLO",
 function(s) { s.result |=  s.snd << (s.si4 & 31) ; },
 function(s) { s.result |= (s.snd << (s.si4 & 15)) & F4; },
    Y.FORM_IRR | Y.FORM_iRR | Y.FORM_RRR,
    Y.IMM16_5LSB | Y.IgnoreImmSign | Y.READ_DST |  Y.OPTIONAL,
 "SHift logic Left and OR");

Y.NewOpcode("ROR",
 function(s) {
   var sa= s.si4 & 31;
   var sb= (32 - sa) & 31;
   s.result = (s.snd << sb) | (s.snd >>> sa);
 },
 function(s) {
   var sa= s.si4 & 15;
   var sb= (16 - sa)  & 15;
   s.result = ((s.snd << sb) | (s.snd >>> sa)) & F4 ;
 }, f,g,
 "ROtate Right");

Y.NewOpcode("ROL",
 function(s) {
   var sa= s.si4 & 31;
   var sb= (32 - sa) & 31;
   s.result = (s.snd << sa) | (s.snd >>> sb) ;
 },
 function(s) {
   var sa= s.si4 & 15;
   var sb= (16 - sa) & 15;
   s.result = ((s.snd << sa) | (s.snd >>> sb)) & F4 ;
 }, f,g,
 "ROtate Left");

Y.NewOpcode("BSWAP",
 function(s) {
   s.result =  (s.snd << 24)
            | ((s.snd & 0xFF00) << 8)
            | ((s.snd >> 8) & 0xFF00)
            | ((s.snd >> 24) & F2);
 },
 function(s) {
   s.result = ((s.snd << 8) | ( (s.snd >> 8) & F2)) & F4 ;
 },
   Y.FORM_RR,
   Y.ALIAS_RR |  Y.IGNORE_SI4 |  Y.OPTIONAL,
 "Switch endianness");
