/* * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The Initial Developer of this code is David Baum. * Portions created by David Baum are Copyright (C) 2000 David Baum. * All Rights Reserved. * * Portions created by John Hansen are Copyright (C) 2005 John Hansen. * All Rights Reserved. * */ #include "ModExpr.h" #include "Bytecode.h" #include "RCX_Cmd.h" #define NON_VOLATILE_MASK (TYPEMASK(kRCX_VariableType) + \ TYPEMASK(kRCX_ConstantType)) Expr* ModExpr::Clone(Mapping *b) const { return new ModExpr(Get(0)->Clone(b), Get(1)->Clone(b)); } bool ModExpr::Evaluate(int &value) const { int v1, v2; if (!Get(0)->Evaluate(v1)) return false; if (!Get(1)->Evaluate(v2)) return false; value = v1 % v2; return true; } RCX_Value ModExpr::EmitAny_(Bytecode &b) const { int dst; dst = GetTempVar(b); if (dst < 0) return kIllegalEA; RCX_Value ea = RCX_VALUE(kRCX_VariableType, dst); if (EmitCalculation(b, dst)) { return ea; } else { b.ReleaseTempEA(ea); return kIllegalEA; } } bool ModExpr::EmitTo_(Bytecode &b, int dst) const { if (Get(1)->Contains(dst) || Get(0)->Contains(dst)) { RCX_Value ea; ea = EmitAny_(b); if (ea==kIllegalEA) return false; b.AddMove(dst, ea); b.ReleaseTempEA(ea); return true; } else { return EmitCalculation(b, dst); } } bool ModExpr::EmitCalculation(Bytecode &b, int dst) const { RCX_Value m, n; RCX_Cmd cmd; m = Get(0)->EmitConstrained(b, NON_VOLATILE_MASK); if (m == kIllegalEA) return false; n = Get(1)->EmitConstrained(b, NON_VOLATILE_MASK); if (n== kIllegalEA) { b.ReleaseTempEA(m); return false; } // dst = m b.AddMove(dst, m); // dst /= n cmd.MakeVar(kRCX_DivVar ,dst, n); b.Add(cmd); // dst *= n cmd.MakeVar(kRCX_MulVar, dst, n); b.Add(cmd); // dst -= m cmd.MakeVar(kRCX_SubVar, dst, m); b.Add(cmd); // dst *= -1 cmd.MakeVar(kRCX_MulVar, dst, RCX_VALUE(kRCX_ConstantType, -1)); b.Add(cmd); b.ReleaseTempEA(m); b.ReleaseTempEA(n); return true ; }