node/lib/metasm/metasm/cpu/x86_64/compile_c.rb
# compile a CExpression with no lexpr
compile a CExpression with no lexpr
compile a CExpression with no lexpr
def c_cexpr_inner_nol(expr)
		case expr.op
		when nil
			r = c_cexpr_inner(expr.rexpr)
			if (expr.rexpr.kind_of? C::CExpression or expr.rexpr.kind_of? C::Variable) and
					expr.type.kind_of? C::BaseType and expr.rexpr.type.kind_of? C::BaseType
				r = c_cexpr_inner_cast(expr, r)
			end
			r
		when :+
			c_cexpr_inner(expr.rexpr)
		when :-
			r = c_cexpr_inner(expr.rexpr)
			r = make_volatile(r, expr.type)
			if expr.type.integral? or expr.type.pointer?
				instr 'neg', r
			elsif expr.type.float?
				raise 'float unhandled'
			else raise
			end
			r
		when :'++', :'--'
			r = c_cexpr_inner(expr.rexpr)
			inc = true if expr.op == :'++'
			if expr.type.integral? or expr.type.pointer?
				op = (inc ? 'inc' : 'dec')
				instr op, r
			elsif expr.type.float?
				raise 'float unhandled'
			end
			r
		when :&
			raise 'bad precompiler ' + expr.to_s if not expr.rexpr.kind_of? C::Variable
			@state.cache.each { |r_, c|
				return inuse(r_) if c.kind_of? Address and c.target == expr.rexpr
			}
			r = c_cexpr_inner(expr.rexpr)
			raise 'bad lvalue' if not r.kind_of? ModRM
			unuse r
			r = Address.new(r)
			inuse r
			r.target = expr.rexpr
			r
		when :*
			expr.rexpr.type.name = :ptr if expr.rexpr.kind_of? C::CExpression and expr.rexpr.type.kind_of? C::BaseType and typesize[expr.rexpr.type.name] == typesize[:ptr]	
			e = c_cexpr_inner(expr.rexpr)
			sz = 8*sizeof(expr)
			case e
			when Address
				unuse e
				e = e.modrm.dup
				e.sz = sz
				inuse e
			when ModRM; e = make_volatile(e, expr.rexpr.type)
			end
			case e
			when Reg; unuse e ; e = inuse ModRM.new(@cpusz, sz, nil, nil, e, nil)
			when Expression; e = inuse ModRM.new(@cpusz, sz, nil, nil, nil, e)
			end
			e
		when :'!'
			r = c_cexpr_inner(expr.rexpr)
			r = make_volatile(r, expr.rexpr.type)
			if expr.rexpr.type.integral? or expr.type.pointer?
				r = make_volatile(r, expr.rexpr.type)
				instr 'test', r, r
			elsif expr.rexpr.type.float?
				raise 'float unhandled'
			else raise 'bad comparison ' + expr.to_s
			end
			instr 'setz', Reg.new(r.val, 8)
			instr 'and', r, Expression[1]
			r
		else raise 'mmh ? ' + expr.to_s
		end
	end
def c_cexpr_inner_nol ( expr ) case expr . op when nil r = c_cexpr_inner ( expr . rexpr ) if ( expr . rexpr . kind_of? C :: CExpression or expr . rexpr . kind_of? C :: Variable ) and expr . type . kind_of? C :: BaseType and expr . rexpr . type . kind_of? C :: BaseType r = c_cexpr_inner_cast ( expr , r ) end r when :+ c_cexpr_inner ( expr . rexpr ) when :- r = c_cexpr_inner ( expr . rexpr ) r = make_volatile ( r , expr . type ) if expr . type . integral? or expr . type . pointer? instr 'neg' , r elsif expr . type . float? raise 'float unhandled' else raise end r when :' ++ ' , :' -- ' r = c_cexpr_inner ( expr . rexpr ) inc = true if expr . op == :' ++ ' if expr . type . integral? or expr . type . pointer? op = ( inc ? 'inc' : 'dec' ) instr op , r elsif expr . type . float? raise 'float unhandled' end r when :& raise 'bad precompiler ' + expr . to_s if not expr . rexpr . kind_of? C :: Variable @state . cache . each { | r_ , c | return inuse ( r_ ) if c . kind_of? Address and c . target == expr . rexpr } r = c_cexpr_inner ( expr . rexpr ) raise 'bad lvalue' if not r . kind_of? ModRM unuse r r = Address . new ( r ) inuse r r . target = expr . rexpr r when :* expr . rexpr . type . name = :ptr if expr . rexpr . kind_of? C :: CExpression and expr . rexpr . type . kind_of? C :: BaseType and typesize [ expr . rexpr . type . name ] == typesize [ :ptr ] e = c_cexpr_inner ( expr . rexpr ) sz = 8 * sizeof ( expr ) case e when Address unuse e e = e . modrm . dup e . sz = sz inuse e when ModRM ; e = make_volatile ( e , expr . rexpr . type ) end case e when Reg ; unuse e ; e = inuse ModRM . new ( @cpusz , sz , nil , nil , e , nil ) when Expression ; e = inuse ModRM . new ( @cpusz , sz , nil , nil , nil , e ) end e when :' ! ' r = c_cexpr_inner ( expr . rexpr ) r = make_volatile ( r , expr . rexpr . type ) if expr . rexpr . type . integral? or expr . type . pointer? r = make_volatile ( r , expr . rexpr . type ) instr 'test' , r , r elsif expr . rexpr . type . float? raise 'float unhandled' else raise 'bad comparison ' + expr . to_s end instr 'setz' , Reg . new ( r . val , 8 ) instr 'and' , r , Expression [ 1 ] r else raise 'mmh ? ' + expr . to_s end end
compile a CExpression with no lexpr
compile a CExpression with no lexpr
# hint to use Address
expr