sem call {
    nPC2 = PC + disp30?sext(32)<<2;
    Rx(15,PC?addr?ext(64));
};

sem jmpl {
    nPC2 = (Rx(rs1) + get_src2(i,rs2,simm13) )?cvt(stream);
    Rx(rd,PC?addr?ext(64));
};

sem retrn {
    nPC2 = (Rx(rs1) + get_src2(i,rs2,simm13) )?cvt(stream);
    if(CANRESTORE?cvt(ulong) > 0) {
	CANSAVE = (CANSAVE?cvt(ulong) + 1)?cvt(cwp_t);
	CANRESTORE = (CANRESTORE?cvt(ulong) - 1)?cvt(cwp_t);
    } else {
	restore_regs(CWP);
	if(CANSAVE?cvt(ulong) < 8 -2)
	    CANSAVE = (CANSAVE?cvt(ulong) + 1)?cvt(cwp_t);
    }
    CWP = ((CWP?cvt(ulong) + 8  - 1) % 8 )?bits(5);
};

sem [ brz brlez brlz brnz brgz brgez ] {
    if(test(Rx(rs1),0?cvt(ullong)))
	nPC2 = PC + ((d16hi?sext(32)<<16) | (d16lo?ext(32)<<2));
    else if(a) annul();
} where test in [ == <= < != > >= ];

sem [ fba ba ] {
    nPC2 = PC + disp22?sext(32)<<2;
    if(a) annul();
};

sem [ fbpa bpa ] {
    nPC2 = PC + disp19?sext(32)<<2;
    if(a) annul();
};

sem [ fbn fbpn bn bpn ] { if(a) annul(); };

sem [			fbu	fbg	fbug	fbl	fbul	fblg
	fbne	fbe	fbue	fbge	fbuge	fble	fbule	fbo	] {
    if(cond(0)) nPC2 = PC + disp22?sext(32)<<2;
    else if(a) annul();
} where cond in [	f_u	f_g	f_ug	f_l	f_ul	f_lg
	f_ne	f_e	f_ue	f_ge	f_uge	f_le	f_ule	f_o	];

sem [			fbpu	fbpg	fbpug	fbpl	fbpul	fbplg
	fbpne	fbpe	fbpue	fbpge	fbpuge	fbple	fbpule	fbpo	] {
    if(cond(bpccr)) nPC2 = PC + disp19?sext(32)<<2;
    else if(a) annul();
} where cond in [	f_u	f_g	f_ug	f_l	f_ul	f_lg
	f_ne	f_e	f_ue	f_ge	f_uge	f_le	f_ule	f_o	];

sem [			bne	be	bg	ble	bge	bl
	bgu	bleu	bcc	bcs	bpos	bneg	bvc	bvs	] {
    if(cond) nPC2 = PC + disp22?sext(32)<<2;
    else if(a) annul();
} where cond in [	(! CCR?bit(2) ) 	(CCR?bit(2) ) 	(!(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) ))) 	(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) )) 	(!(CCR?bit(3) ^ CCR?bit(1) )) 	(CCR?bit(3) ^ CCR?bit(1) ) 
	(!(CCR?bit(0) | CCR?bit(2) )) 	(CCR?bit(0) | CCR?bit(2) ) 	(! CCR?bit(0) ) 	(CCR?bit(0) ) 	(! CCR?bit(3) ) 	(CCR?bit(3) ) 	(! CCR?bit(1) ) 	(CCR?bit(1) ) 	];

sem [			bpne	bpe	bpg	bple	bpge	bpl
	bpgu	bpleu	bpcc	bpcs	bppos	bpneg	bpvc	bpvs	] {
    if(bpcc1) {
	if(cond_xcc) nPC2 = PC + disp19?sext(32)<<2;
	else if(a) annul();
    } else if(cond_icc) nPC2 = PC + disp19?sext(32)<<2;
    else if(a) annul();
} where cond_xcc in [	(! CCR?bit(6) ) 	(CCR?bit(6) ) 	(!(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) ))) 	(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) )) 	(!(CCR?bit(7) ^ CCR?bit(5) )) 	(CCR?bit(7) ^ CCR?bit(5) ) 
	(!(CCR?bit(4) | CCR?bit(6) )) 	(CCR?bit(4) | CCR?bit(6) ) 	(! CCR?bit(4) ) 	(CCR?bit(4) ) 	(! CCR?bit(7) ) 	(CCR?bit(7) ) 	(! CCR?bit(5) ) 	(CCR?bit(5) ) 	],
	cond_icc in [	(! CCR?bit(2) ) 	(CCR?bit(2) ) 	(!(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) ))) 	(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) )) 	(!(CCR?bit(3) ^ CCR?bit(1) )) 	(CCR?bit(3) ^ CCR?bit(1) ) 
	(!(CCR?bit(0) | CCR?bit(2) )) 	(CCR?bit(0) | CCR?bit(2) ) 	(! CCR?bit(0) ) 	(CCR?bit(0) ) 	(! CCR?bit(3) ) 	(CCR?bit(3) ) 	(! CCR?bit(1) ) 	(CCR?bit(1) ) 	];

sem [ fmovfsa fmovfda fmovsa fmovda ] { fd(rd,fs(rs2)); }
where fs in [ F4 F8 F4 F8 ], fd in [ F4 F8 F4 F8 ];

sem [					fmovsne		fmovse
	fmovsg		fmovsle		fmovsge		fmovsl
	fmovsgu		fmovsleu	fmovscc		fmovscs
	fmovspos	fmovsneg	fmovsvc		fmovsvs	] {
    if(bpcc1) { if(cond_xcc) F4(rd,F4(rs2)); }
    else if(cond_icc) F4(rd,F4(rs2));
} where cond_xcc in [	(! CCR?bit(6) ) 	(CCR?bit(6) ) 	(!(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) ))) 	(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) )) 	(!(CCR?bit(7) ^ CCR?bit(5) )) 	(CCR?bit(7) ^ CCR?bit(5) ) 
	(!(CCR?bit(4) | CCR?bit(6) )) 	(CCR?bit(4) | CCR?bit(6) ) 	(! CCR?bit(4) ) 	(CCR?bit(4) ) 	(! CCR?bit(7) ) 	(CCR?bit(7) ) 	(! CCR?bit(5) ) 	(CCR?bit(5) ) 	],
	cond_icc in [	(! CCR?bit(2) ) 	(CCR?bit(2) ) 	(!(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) ))) 	(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) )) 	(!(CCR?bit(3) ^ CCR?bit(1) )) 	(CCR?bit(3) ^ CCR?bit(1) ) 
	(!(CCR?bit(0) | CCR?bit(2) )) 	(CCR?bit(0) | CCR?bit(2) ) 	(! CCR?bit(0) ) 	(CCR?bit(0) ) 	(! CCR?bit(3) ) 	(CCR?bit(3) ) 	(! CCR?bit(1) ) 	(CCR?bit(1) ) 	];

sem [					fmovdne		fmovde
	fmovdg		fmovdle		fmovdge		fmovdl
	fmovdgu		fmovdleu	fmovdcc		fmovdcs
	fmovdpos	fmovdneg	fmovdvc		fmovdvs	] {
    if(bpcc1) { if(cond_xcc) F8(rd,F8(rs2)); }
    else if(cond_icc) F8(rd,F8(rs2));
} where cond_xcc in [	(! CCR?bit(6) ) 	(CCR?bit(6) ) 	(!(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) ))) 	(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) )) 	(!(CCR?bit(7) ^ CCR?bit(5) )) 	(CCR?bit(7) ^ CCR?bit(5) ) 
	(!(CCR?bit(4) | CCR?bit(6) )) 	(CCR?bit(4) | CCR?bit(6) ) 	(! CCR?bit(4) ) 	(CCR?bit(4) ) 	(! CCR?bit(7) ) 	(CCR?bit(7) ) 	(! CCR?bit(5) ) 	(CCR?bit(5) ) 	],
	cond_icc in [	(! CCR?bit(2) ) 	(CCR?bit(2) ) 	(!(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) ))) 	(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) )) 	(!(CCR?bit(3) ^ CCR?bit(1) )) 	(CCR?bit(3) ^ CCR?bit(1) ) 
	(!(CCR?bit(0) | CCR?bit(2) )) 	(CCR?bit(0) | CCR?bit(2) ) 	(! CCR?bit(0) ) 	(CCR?bit(0) ) 	(! CCR?bit(3) ) 	(CCR?bit(3) ) 	(! CCR?bit(1) ) 	(CCR?bit(1) ) 	];

sem [					fmovfsu		fmovfsg
	fmovfsug	fmovfsl		fmovfsul	fmovfslg
	fmovfsne	fmovfse		fmovfsue	fmovfsge
	fmovfsuge	fmovfsle	fmovfsule	fmovfso	] {
    if(cond(bpccr)) F4(rd,F4(rs2));
} where cond in [	f_u	f_g	f_ug	f_l	f_ul	f_lg
	f_ne	f_e	f_ue	f_ge	f_uge	f_le	f_ule	f_o	];

sem [					fmovfdu		fmovfdg
	fmovfdug	fmovfdl		fmovfdul	fmovfdlg
	fmovfdne	fmovfde		fmovfdue	fmovfdge
	fmovfduge	fmovfdle	fmovfdule	fmovfdo	] {
    if(cond(bpccr)) F8(rd,F8(rs2));
} where cond in [	f_u	f_g	f_ug	f_l	f_ul	f_lg
	f_ne	f_e	f_ue	f_ge	f_uge	f_le	f_ule	f_o	];

sem [ fmovrsz fmovrslez fmovrslz fmovrsnz fmovrsgz fmovrsgez ]
{ if(test(Rx(rs1),0?cvt(ullong))) F4(rd,F4(rs2)); }
where test in [ == <= < != > >= ];

sem [ fmovrdz fmovrdlez fmovrdlz fmovrdnz fmovrdgz fmovrdgez ]
{ if(test(Rx(rs1),0?cvt(ullong))) F8(rd,F8(rs2)); }
where test in [ == <= < != > >= ];

sem [ mova movfa ] { Rx(rd,Rx(rs2)); };

sem [					movne		move
	movg		movle		movge		movl
	movgu		movleu		movcc		movcs
	movpos		movneg		movvc		movvs	] {
    if(bpcc1) { if(cond_xcc) Rx(rd,Rx(rs2)); }
    else if(cond_icc) Rx(rd,Rx(rs2));
} where cond_xcc in [	(! CCR?bit(6) ) 	(CCR?bit(6) ) 	(!(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) ))) 	(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) )) 	(!(CCR?bit(7) ^ CCR?bit(5) )) 	(CCR?bit(7) ^ CCR?bit(5) ) 
	(!(CCR?bit(4) | CCR?bit(6) )) 	(CCR?bit(4) | CCR?bit(6) ) 	(! CCR?bit(4) ) 	(CCR?bit(4) ) 	(! CCR?bit(7) ) 	(CCR?bit(7) ) 	(! CCR?bit(5) ) 	(CCR?bit(5) ) 	],
	cond_icc in [	(! CCR?bit(2) ) 	(CCR?bit(2) ) 	(!(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) ))) 	(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) )) 	(!(CCR?bit(3) ^ CCR?bit(1) )) 	(CCR?bit(3) ^ CCR?bit(1) ) 
	(!(CCR?bit(0) | CCR?bit(2) )) 	(CCR?bit(0) | CCR?bit(2) ) 	(! CCR?bit(0) ) 	(CCR?bit(0) ) 	(! CCR?bit(3) ) 	(CCR?bit(3) ) 	(! CCR?bit(1) ) 	(CCR?bit(1) ) 	];

sem [			movfu	movfg	movfug	movfl	movful	movflg
	movfne	movfe	movfue	movfge	movfuge	movfle	movfule	movfo	] {
    if(cond(bpccr)) Rx(rd,Rx(rs2));
} where cond in [	f_u	f_g	f_ug	f_l	f_ul	f_lg
	f_ne	f_e	f_ue	f_ge	f_uge	f_le	f_ule	f_o	];

sem [ movrz movrlez movrlz movrnz movrgz movrgez ]
{ if(test(Rx(rs1),0?cvt(ullong))) Rx(rd,Rx(rs2)); }
where test in [ == <= < != > >= ];

sem ta { _trap(i,rs2,sw_trap) ; };

sem [			tne	te	tg	tle	tge	tl
	tgu	tleu	tcc	tcs	tpos	tneg	tvc	tvs	] {
    if(bpcc1) { if(cond_xcc) _trap(i,rs2,sw_trap) ; }
    else if(cond_icc) _trap(i,rs2,sw_trap) ;
} where cond_xcc in [	(! CCR?bit(6) ) 	(CCR?bit(6) ) 	(!(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) ))) 	(CCR?bit(6) |(CCR?bit(7) ^ CCR?bit(5) )) 	(!(CCR?bit(7) ^ CCR?bit(5) )) 	(CCR?bit(7) ^ CCR?bit(5) ) 
	(!(CCR?bit(4) | CCR?bit(6) )) 	(CCR?bit(4) | CCR?bit(6) ) 	(! CCR?bit(4) ) 	(CCR?bit(4) ) 	(! CCR?bit(7) ) 	(CCR?bit(7) ) 	(! CCR?bit(5) ) 	(CCR?bit(5) ) 	],
	cond_icc in [	(! CCR?bit(2) ) 	(CCR?bit(2) ) 	(!(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) ))) 	(CCR?bit(2) |(CCR?bit(3) ^ CCR?bit(1) )) 	(!(CCR?bit(3) ^ CCR?bit(1) )) 	(CCR?bit(3) ^ CCR?bit(1) ) 
	(!(CCR?bit(0) | CCR?bit(2) )) 	(CCR?bit(0) | CCR?bit(2) ) 	(! CCR?bit(0) ) 	(CCR?bit(0) ) 	(! CCR?bit(3) ) 	(CCR?bit(3) ) 	(! CCR?bit(1) ) 	(CCR?bit(1) ) 	];

sem [ add sub and or xor ]
{ Rx(rd, op(Rx(rs1),get_src2(i,rs2,simm13) )); }
where op in [ + - & | ^ ];

sem [ addcc subcc andcc orcc xorcc ]
{ Rx(rd, op(Rx(rs1),get_src2(i,rs2,simm13) )?cc(CCR)); }
where op in [ + - & | ^ ];

sem addc { Rx(rd, Rx(rs1) + get_src2(i,rs2,simm13)  + (CCR?bit(0)?ext(64)) ); };

sem subc { Rx(rd, Rx(rs1) - get_src2(i,rs2,simm13)  - (CCR?bit(0)?ext(64)) ); };

sem addccc {
    val ccr = 0x00?cvt(cc);
    val x1 = Rx(rs1); val x2 = get_src2(i,rs2,simm13) ;
    val xx = ((x1 + x2)?cc(ccr) + (CCR?bit(0)?ext(64)) )?cc(CCR);
    CCR = ((CCR?bits(8) & 0b11011101) | (ccr?bits(8) & 0x11) |
	   (((x1?bit(31)==x2?bit(31))&&(xx?bit(31)!=x1?bit(31)))?ext(8)<<1) |
	   (((x1?bit(63)==x2?bit(63))&&(xx?bit(63)!=x1?bit(63)))?ext(8)<<5))
	? cvt(cc);
    Rx(rd, xx);
};

sem subccc {
    val ccr = 0x00?cvt(cc);
    val x1 = Rx(rs1); val x2 = get_src2(i,rs2,simm13) ;
    val xx = ((x1 - x2)?cc(ccr) - (CCR?bit(0)?ext(64)) )?cc(CCR);
    CCR = ((CCR?bits(8) & 0b11011101) | (ccr?bits(8) & 0x11) |
	   (((x1?bit(31)!=x2?bit(31))&&(xx?bit(31)!=x1?bit(31)))?ext(8)<<1) |
	   (((x1?bit(63)!=x2?bit(63))&&(xx?bit(63)!=x1?bit(63)))?ext(8)<<5))
	? cvt(cc);
    Rx(rd, xx);
};

sem [ andn orn xnor ] { Rx(rd, op(Rx(rs1),~get_src2(i,rs2,simm13) )); } where op in [ & | ^ ];

sem [ andncc orncc xnorcc ]
{ Rx(rd, op(Rx(rs1),~get_src2(i,rs2,simm13) )?cc(CCR)); }
where op in [ & | ^ ];

sem [ mulx udivx ] { Rx(rd,  op(Rx(rs1),get_src2(i,rs2,simm13) )); } where op in [ * / ];

sem sdivx { Rx(rd,(+Rx(rs1) / + get_src2(i,rs2,simm13) )?cast(ullong)); };

sem sll		{ Rx(rd,  Rx(rs1) << get_src2(i,rs2,simm13) ?bits(5)); };

sem srl		{ R4(rd,  R4(rs1) >> get_src2(i,rs2,simm13) ?bits(5)); };

sem sra		{ Rx(rd,(+R4(rs1) >> get_src2(i,rs2,simm13) ?bits(5))?sext(64)); };

sem sllx	{ Rx(rd,  Rx(rs1) << get_src2(i,rs2,simm13) ?bits(6)); };

sem srlx	{ Rx(rd,  Rx(rs1) >> get_src2(i,rs2,simm13) ?bits(6)); };

sem srax	{ Rx(rd,(+Rx(rs1) >> get_src2(i,rs2,simm13) ?bits(6))?cast(ullong)); };

sem taddcc {
    val x1 = Rx(rs1); val x2 = get_src2(i,rs2,simm13) ;
    Rx(rd, (x1 + x2)?cc(CCR));
    if(x1?bits(2)!=0b00 || x2?bits(2)!=0b00)
	CCR = (CCR?bits(8) | 0x02)?cvt(cc);
};

sem taddcctv {
    val x1 = Rx(rs1); val x2 = get_src2(i,rs2,simm13) ;
    Rx(rd, (x1 + x2)?cc(CCR));
    if(x1?bits(2)!=0b00 || x2?bits(2)!=0b00)
	CCR = (CCR?bits(8) | 0x02)?cvt(cc);
    if(CCR?bit(1)) trap_sparc(0x23?ext(32) ,CWP,CANRESTORE);
};

sem tsubcc {
    val x1 = Rx(rs1); val x2 = get_src2(i,rs2,simm13) ;
    Rx(rd, (x1 - x2)?cc(CCR));
    if(x1?bits(2)!=0b00 || x2?bits(2)!=0b00)
	CCR = (CCR?bits(8) | 0x02)?cvt(cc);
};

sem tsubcctv {
    val x1 = Rx(rs1); val x2 = get_src2(i,rs2,simm13) ;
    Rx(rd, (x1 - x2)?cc(CCR));
    if(x1?bits(2)!=0b00 || x2?bits(2)!=0b00)
	CCR = (CCR?bits(8) | 0x02)?cvt(cc);
    if(CCR?bit(1)) trap_sparc(0x23?ext(32) ,CWP,CANRESTORE);
};

sem [ udiv sdiv ] {
    val ccr = 0x00;
    val xx = ((Y?ext(64)<<32) | R4(rs1)?ext(64));
    if(i) xx = _div(xx,simm13?sext(32)?ext(64),ccr);
    else xx = _div(xx,R4(rs2)?ext(64),ccr);
    Rx(rd,xx);
} where _div in [u_div32 s_div32];

sem umul {
    val xx = (Rx(rs1)&0xffffffff?ext(64)) * (get_src2(i,rs2,simm13) &0xffffffff?ext(64)); 
    Y = (xx >> 32)?bits(32); R4(rd,xx?bits(32));
};

sem smul {
    val xx = +Rx(rs1)?bits(32)?sext(64) * + get_src2(i,rs2,simm13) ?bits(32)?sext(64);
    Y = (xx >> 32)?bits(32); R4(rd,xx?bits(32));
};

sem [ udivcc sdivcc ] {
    val ccr = 0x00;
    val xx = ((Y?ext(64)<<32) | R4(rs1)?ext(64));
    if(i) xx = _div(xx,simm13?sext(32),ccr);
    else xx = _div(xx,R4(rs2),ccr);
    CCR = get_div_mul_cc(xx,ccr)?cvt(cc);
    Rx(rd,xx);
} where _div in [u_div32 s_div32];

sem umulcc {
    val xx = (Rx(rs1)&0xffffffff?ext(64)) * (get_src2(i,rs2,simm13) &0xffffffff?ext(64)); 
    CCR = get_div_mul_cc(xx,0x00)?cvt(cc);
    Y = (xx >> 32)?bits(32); R4(rd,xx?bits(32));
};

sem smulcc {
    val xx = (+Rx(rs1)?bits(32)?sext(64) *
	      + get_src2(i,rs2,simm13) ?bits(32)?sext(64))?cast(ullong);
    CCR = get_div_mul_cc(xx,0x00)?cvt(cc);
    Y = (xx >> 32)?bits(32); R4(rd,xx?bits(32));
};

sem mulscc {
    val y0 = Y?bit(0); Y = (Y>>1) | (R4(rs1)?bit(0)?ext(32)<<31);
    val xx = (R4(rs1)>>1) | ((CCR?bit(3)^CCR?bit(1))?ext(32)<<31);
    if(y0) R4(rd, (xx + get_src2(i,rs2,simm13) ?bits(32))?cc(CCR));
    else R4(rd,(xx+0)?cc(CCR));
};

sem popc {
    val xx = Rx(rs2);
    val ii=0; val count=0?ext(64);
    while(ii < 64) {
	count = count + ((xx >> ii) & 0x1?ext(64));
	ii = ii + 1;
    }
    Rx(rd,count);
};

sem flushw { _flushw() ; };

sem rd {
    switch(rs1?ext(32)) {
     case 0:	Rx(rd,Y?ext(64));
     case 2:	Rx(rd,CCR?bits(8)?ext(64));
     case 5:	Rx(rd,PC?addr?ext(64));
     case 15:	assert(rd?ext(32)==0);
     default:
	 
	assert(false);
    }
};

sem wr {
    switch(rd?ext(32)) {
     case 0:	Y = (Rx(rs1) ^ get_src2(i,rs2,simm13) )?bits(32);
     case 2:	CCR = (Rx(rs1) ^ get_src2(i,rs2,simm13) )?cvt(cc);
     default:
	 
	assert(false);
    }
};

sem save {
    val xx = Rx(rs1) + get_src2(i,rs2,simm13) ;
    if(CANSAVE?cvt(ulong) <= 0) {
	save_regs(CWP,CANRESTORE);
	CANSAVE = CANRESTORE; CANRESTORE = 0?cvt(cwp_t);
    }
    CWP = ((CWP?cvt(ulong) + 1) % 8 )?bits(5);
    CANSAVE = (CANSAVE?cvt(ulong) - 1)?cvt(cwp_t);
    CANRESTORE = (CANRESTORE?cvt(ulong) + 1)?cvt(cwp_t);
    Rx(rd,xx);
};

sem restore {
    val xx = Rx(rs1) + get_src2(i,rs2,simm13) ;
    if(CANRESTORE?cvt(ulong) > 0) {
	CANSAVE = (CANSAVE?cvt(ulong) + 1)?cvt(cwp_t);
	CANRESTORE = (CANRESTORE?cvt(ulong) - 1)?cvt(cwp_t);
    } else {
	restore_regs(CWP);
	if(CANSAVE?cvt(ulong) < 8 -2)
	    CANSAVE = (CANSAVE?cvt(ulong) + 1)?cvt(cwp_t);
    }
    CWP = ((CWP?cvt(ulong) + 8  - 1) % 8 )?bits(5);
    Rx(rd,xx);
};

sem sethi { Rx(rd,imm22?ext(64)<<10); };

sem [ fadds fsubs fmuls fdivs ]
{ F4(rd, op(F4(rs1),F4(rs2))); }
where op in [ + - * / ];

sem [ faddd fsubd fmuld fdivd ]
{ F8(rd, op(F8(rs1),F8(rs2))); }
where op in [ + - * / ];

sem [ fcmps fcmpd ] { (f(rs1)-f(rs2))?cc(fcc[cond]); } where f in [F4 F8];

sem [ fcmpes fcmped ] {
    (f(rs1)-f(rs2))?cc(fcc[cond]);
    if(f_u(cond)) trap_sparc(0x21?ext(32) ,CWP,CANRESTORE);
} where f in [F4 F8];

sem fstox { F8(rd,F4(rs2)?cvt(llong)?cast(ullong)); };

sem fdtox { F8(rd,F8(rs2)?cvt(llong)?cast(ullong)); };

sem fstoi { F4(rd,F4(rs2)?cvt(long)?cast(ulong)); };

sem fdtoi { F4(rd,F8(rs2)?cvt(long)?cast(ulong)); };

sem fstod { F8(rd,F4(rs2)?cvt(double)); };

sem fxtos { F4(rd,F8(rs2)?cast(llong)?cvt(float)); };

sem fxtod { F8(rd,F8(rs2)?cast(llong)?cvt(double)); };

sem fitos { F4(rd,F4(rs2)?cast(long)?cvt(float)); };

sem fitod { F8(rd,F4(rs2)?cast(long)?cvt(double)); };

sem fdtos { F4(rd,F8(rs2)?cvt(float)); };

sem [ fmovs fmovd ] { fd(rd,fs(rs2)); } where fs in [F4 F8], fd in [F4 F8];

sem [ fnegs fnegd ] { fd(rd,-fs(rs2)); } where fs in [F4 F8], fd in [F4 F8];

sem [ fabss fabsd ] { if(fs(rs2)<z) fd(rd,-fs(rs2)); else fd(rd,fs(rs2)); }
where fs in [F4 F8], fd in [F4 F8], z in [ (0?cvt(float)) (0?cvt(double)) ];

sem fsmuld { F8(rd, F4(rs1)?cvt(double) * F4(rs2)?cvt(double)); };

sem [fsqrts fsqrtd] {fd(rd,sqrt(fs(rs2)));} where fs in [F4 F8], fd in [F4 F8];

sem [			ldf	lddf		ldfa	lddfa
	ldsb	ldsh	ldsw	ldub	lduh	lduw	ldx	ldd
	ldsba	ldsha	ldswa	lduba	lduha	lduwa	ldxa	ldda	] {
    r(rd, m(Rx(rs1) + get_src2(i,rs2,simm13) ));
} where r in [		F4	F8		F4	F8
	Rx	Rx	Rx	Rx	Rx	Rx	Rx	R8
	Rx	Rx	Rx	Rx	Rx	Rx	Rx	R8	],
	m in [		M4	M8		M4	M8
	M1s	M2s	M4s	M1	M2	M4	M8	M8
	M1s	M2s	M4s	M1	M2	M4	M8	M8	];

sem [		stf	stdf	stb	sth	stw	stx	std
		stfa	stdfa	stba	stha	stwa	stxa	stda	] {
    m(Rx(rs1) + get_src2(i,rs2,simm13) , r(rd));
} where r in [	F4	F8	Rx	Rx	Rx	Rx	R8
		F4	F8	Rx	Rx	Rx	Rx	R8	],
	m in [	M4	M8	M1	M2	M4	M8	M8
		M4	M8	M1	M2	M4	M8	M8	];

sem [ casa casxa ] {
    val aa = Rx(rs1); val xx = ms(aa);
    if(rsrc(rs2)?ext(64) == xx) md(aa,rsrc(rd)); rdest(rd,xx);
} where rsrc in [R4 Rx], rdest in [R4 Rx],
	ms in [M4 M8], md in [M4 M8];

sem [ ldstub ldstuba ] { val aa=Rx(rs1)+ get_src2(i,rs2,simm13) ; Rx(rd,M1(aa)); M1(aa,0xff); };

sem [ swap swapa ] {
    val aa = Rx(rs1) + get_src2(i,rs2,simm13) ; val xx = M4(aa);
    M4(aa,R4(rd)); R4(rd,xx);
};

sem ldfsr { set_FSR4(M4(Rx(rs1) + get_src2(i,rs2,simm13) )?bits(32)); };

sem ldxfsr { set_FSR8(M8(Rx(rs1) + get_src2(i,rs2,simm13) )); };

sem [ stfsr stxfsr ] { m(Rx(rs1) + get_src2(i,rs2,simm13) , r()); }
where r in [ get_FSR4 get_FSR8 ], m in [ M4 M8 ];