Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit 57e8ce7

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
Generate correct code for integer mod(i1,i2)
Changed Ceval/ExpressionSimplify to use the mod calls. Belonging to [master]: - #2432
1 parent 17adb9a commit 57e8ce7

File tree

6 files changed

+55
-102
lines changed

6 files changed

+55
-102
lines changed

Compiler/FrontEnd/Ceval.mo

Lines changed: 25 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3263,101 +3263,48 @@ protected function cevalBuiltinMod "author: LP
32633263
input FCore.Cache inCache;
32643264
input FCore.Graph inEnv;
32653265
input list<DAE.Exp> inExpExpLst;
3266-
input Boolean inBoolean;
3267-
input Absyn.Msg inMsg;
3266+
input Boolean impl;
3267+
input Absyn.Msg msg;
32683268
input Integer numIter;
3269-
output FCore.Cache outCache;
3269+
output FCore.Cache cache = inCache;
32703270
output Values.Value outValue;
3271+
protected
3272+
Values.Value v1, v2;
3273+
DAE.Exp exp1,exp2;
32713274
algorithm
3272-
(outCache,outValue):=
3273-
matchcontinue (inCache,inEnv,inExpExpLst,inBoolean,inMsg,numIter)
3275+
{exp1,exp2} := inExpExpLst;
3276+
(cache,v1) := ceval(cache,inEnv, exp1, impl, msg,numIter+1);
3277+
(cache,v2) := ceval(cache,inEnv, exp2, impl, msg,numIter+1);
3278+
outValue := match (v1,v2,msg)
32743279
local
3275-
Real rv1,rv2,rva,rvb,rvc,rvd;
3276-
FCore.Graph env;
3277-
DAE.Exp exp1,exp2;
3278-
Boolean impl;
3279-
Absyn.Msg msg;
3280-
Integer ri,ri1,ri2,ri_1;
3280+
Real rv1,rv2;
3281+
Integer ri,ri1,ri2;
32813282
String lhs_str,rhs_str;
3282-
FCore.Cache cache;
32833283
SourceInfo info;
32843284

3285-
case (cache,env,{exp1,exp2},impl,msg,_)
3286-
equation
3287-
(cache,Values.REAL(rv1)) = ceval(cache,env, exp1, impl, msg,numIter+1);
3288-
(cache,Values.REAL(rv2)) = ceval(cache,env, exp2, impl, msg,numIter+1);
3289-
rva = rv1 / rv2;
3290-
rvb = floor(rva);
3291-
rvc = rvb * rv2;
3292-
rvd = rv1 - rvc;
3293-
then
3294-
(cache,Values.REAL(rvd));
3295-
case (cache,env,{exp1,exp2},impl,msg,_)
3296-
equation
3297-
(cache,Values.INTEGER(ri)) = ceval(cache,env, exp1, impl, msg,numIter+1);
3298-
rv1 = intReal(ri);
3299-
(cache,Values.REAL(rv2)) = ceval(cache,env, exp2, impl, msg,numIter+1);
3300-
rva = rv1 / rv2;
3301-
rvb = floor(rva);
3302-
rvc = rvb * rv2;
3303-
rvd = rv1 - rvc;
3304-
then
3305-
(cache,Values.REAL(rvd));
3306-
case (cache,env,{exp1,exp2},impl,msg,_)
3307-
equation
3308-
(cache,Values.REAL(rv1)) = ceval(cache,env, exp1, impl, msg,numIter+1);
3309-
(cache,Values.INTEGER(ri)) = ceval(cache,env, exp2, impl, msg,numIter+1);
3310-
rv2 = intReal(ri);
3311-
rva = rv1 / rv2;
3312-
rvb = floor(rva);
3313-
rvc = rvb * rv2;
3314-
rvd = rv1 - rvc;
3315-
then
3316-
(cache,Values.REAL(rvd));
3317-
case (cache,env,{exp1,exp2},impl,msg,_)
3318-
equation
3319-
(cache,Values.INTEGER(ri1)) = ceval(cache,env, exp1, impl, msg,numIter+1);
3320-
(cache,Values.INTEGER(ri2)) = ceval(cache,env, exp2, impl, msg,numIter+1);
3321-
rv1 = intReal(ri1);
3322-
rv2 = intReal(ri2);
3323-
rva = rv1 / rv2;
3324-
rvb = floor(rva);
3325-
rvc = rvb * rv2;
3326-
rvd = rv1 - rvc;
3327-
ri_1 = integer(rvd);
3328-
then
3329-
(cache,Values.INTEGER(ri_1));
3330-
case (cache,env,{exp1,exp2},impl,Absyn.MSG(info = info),_)
3285+
case (Values.REAL(rv1),Values.REAL(rv2),_)
3286+
then (Values.REAL(mod(rv1,rv2)));
3287+
case (Values.INTEGER(ri),Values.REAL(rv2),_)
3288+
then (Values.REAL(mod(ri,rv2)));
3289+
case (Values.REAL(rv1),Values.INTEGER(ri),_)
3290+
then (Values.REAL(mod(rv1,ri)));
3291+
case (Values.INTEGER(ri1),Values.INTEGER(ri2),_)
3292+
then (Values.INTEGER(mod(ri1,ri2)));
3293+
case (_,Values.REAL(rv2),Absyn.MSG(info = info))
3294+
guard rv2 == 0.0
33313295
equation
3332-
(_,Values.REAL(rv2)) = ceval(cache,env, exp2, impl, inMsg,numIter+1);
3333-
(rv2 == 0.0) = true;
33343296
lhs_str = ExpressionDump.printExpStr(exp1);
33353297
rhs_str = ExpressionDump.printExpStr(exp2);
33363298
Error.addSourceMessage(Error.MODULO_BY_ZERO, {lhs_str,rhs_str}, info);
3337-
then
3338-
fail();
3339-
case (cache,env,{_,exp2},impl,Absyn.NO_MSG(),_)
3340-
equation
3341-
(_,Values.REAL(rv2)) = ceval(cache,env, exp2, impl, Absyn.NO_MSG(),numIter+1);
3342-
(rv2 == 0.0) = true;
3343-
then
3344-
fail();
3345-
case (cache,env,{exp1,exp2},impl,Absyn.MSG(info = info),_)
3299+
then fail();
3300+
case (_,Values.INTEGER(0),Absyn.MSG(info = info))
33463301
equation
3347-
(_,Values.INTEGER(ri2)) = ceval(cache,env, exp2, impl, inMsg,numIter+1);
3348-
(ri2 == 0) = true;
33493302
lhs_str = ExpressionDump.printExpStr(exp1);
33503303
rhs_str = ExpressionDump.printExpStr(exp2);
33513304
Error.addSourceMessage(Error.MODULO_BY_ZERO, {lhs_str,rhs_str}, info);
33523305
then
33533306
fail();
3354-
case (cache,env,{_,exp2},impl,Absyn.NO_MSG(),_)
3355-
equation
3356-
(_,Values.INTEGER(ri2)) = ceval(cache,env, exp2, impl, Absyn.NO_MSG(),numIter+1);
3357-
(ri2 == 0) = true;
3358-
then
3359-
fail();
3360-
end matchcontinue;
3307+
end match;
33613308
end cevalBuiltinMod;
33623309

33633310
protected function cevalBuiltinSum "Evaluates the builtin sum function."

Compiler/FrontEnd/ExpressionSimplify.mo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,10 +503,10 @@ algorithm
503503

504504
// modulo for real values
505505
case (DAE.CALL(path=Absyn.IDENT("mod"),expLst={DAE.RCONST(r1),DAE.RCONST(r2)}))
506-
then DAE.RCONST(r1-floor(r1/r2)*r2);
506+
then DAE.RCONST(mod(r1,r2));
507507
// modulo for integer values
508508
case (DAE.CALL(path=Absyn.IDENT("mod"),expLst={DAE.ICONST(i1),DAE.ICONST(i2)}))
509-
then DAE.ICONST(realInt(intReal(i1)-floor(intReal(i1)/intReal(i2))*intReal(i2)));
509+
then DAE.ICONST(mod(i1,i2));
510510
// integer call
511511
case (DAE.CALL(path=Absyn.IDENT("integer"),expLst={DAE.RCONST(r1)}))
512512
then DAE.ICONST(realInt(r1));

Compiler/Template/CodegenCFunctions.tpl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5690,17 +5690,18 @@ template daeExpCall(Exp call, Context context, Text &preExp, Text &varDecls, Tex
56905690
let exp = daeExp(inExp, context, &preExp, &varDecls, &auxFunction)
56915691
'((modelica_integer)floor(<%exp%>))'
56925692

5693-
case CALL(path=IDENT(name="mod"), expLst={e1,e2}, attr=CALL_ATTR(ty=T_INTEGER(__))) then
5693+
case CALL(path=IDENT(name="mod"), expLst={e1,e2}, attr=CALL_ATTR(ty=ty)) then
5694+
let tp_str = expTypeModelica(ty)
56945695
let var1 = daeExp(e1, context, &preExp, &varDecls, &auxFunction)
56955696
let var2 = daeExp(e2, context, &preExp, &varDecls, &auxFunction)
5696-
let tvar = tempDecl("modelica_integer", &varDecls)
5697+
let tvar = if acceptMetaModelicaGrammar() then '<%var2%>' else tempDecl(tp_str, &varDecls)
56975698
let cstr = ExpressionDumpTpl.dumpExp(call,"\"")
5698-
let &preExp += '<%tvar%> = <%var2%>;<%\n%>'
5699+
let &preExp += if acceptMetaModelicaGrammar() then "" else '<%tvar%> = <%var2%>;<%\n%>'
56995700
let &preExp +=
57005701
if acceptMetaModelicaGrammar()
5701-
then 'if (<%tvar%> == 0) {<%generateThrow()%>;}<%\n%>'
5702+
then ""
57025703
else 'if (<%tvar%> == 0) {throwStreamPrint(threadData, "Division by zero %s", "<%Util.escapeModelicaStringToCString(cstr)%>");}<%\n%>'
5703-
'((<%var1%>) - ((<%var1%>) / <%tvar%>) * <%tvar%>)'
5704+
'<%tp_str%>_mod(<%var1%>, <%tvar%>)'
57045705

57055706
case CALL(path=IDENT(name="mod"), expLst={e1,e2}) then
57065707
let var1 = daeExp(e1, context, &preExp, &varDecls, &auxFunction)

Compiler/boot/Makefile.common

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ bootstrap-from-tarball:
7676
echo '#include "Patternm.h"' >> build/SimCodeFunctionUtil_includes.h
7777
# We have not compiled OpenModelicaScriptingAPI.mo yet
7878
touch build/OpenModelicaScriptingAPI.h
79-
$(MAKE) -f $(defaultMakefileTarget) install INCLUDESOURCES=1 OMC="$(BOOTSTRAP_OMC)" BOOTSTRAP_OMHOME=1
79+
$(MAKE) -f $(defaultMakefileTarget) install INCLUDESOURCES=1 OMC="$(BOOTSTRAP_OMC)" CPPFLAGS="$(CPPFLAGS) -DOMC_BOOTSTRAPPING_STAGE_2" BOOTSTRAP_OMHOME=1
8080
@echo "Bootstrapping phase 2/3 completed"
8181
$(MAKE) -f $(defaultMakefileTarget) clean OMC="$(BOOTSTRAP_OMC)"
8282
$(MAKE) -f $(defaultMakefileTarget) --no-print-directory -C $(TOP_DIR)/Compiler/Template OMC="$(BOOTSTRAP_OMC)" clean

SimulationRuntime/c/meta/meta_modelica_builtin_boxptr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ boxptr_binOp(boxptr_intAdd,mmc_mk_icon,mmc_unbox_integer,+)
6565
boxptr_binOp(boxptr_intSub,mmc_mk_icon,mmc_unbox_integer,-)
6666
boxptr_binOp(boxptr_intMul,mmc_mk_icon,mmc_unbox_integer,*)
6767
boxptr_binOp(boxptr_intDiv,mmc_mk_icon,mmc_unbox_integer,/)
68-
boxptr_binFn(boxptr_intMod,mmc_mk_icon,mmc_unbox_integer,modelica_mod_integer)
68+
boxptr_binFn(boxptr_intMod,mmc_mk_icon,mmc_unbox_integer,modelica_integer_mod)
6969
boxptr_unOp(boxptr_intAbs,mmc_mk_icon,mmc_unbox_integer,labs)
7070
boxptr_unOp(boxptr_intNeg,mmc_mk_icon,mmc_unbox_integer,-)
7171
boxptr_binFn(boxptr_intMin,mmc_mk_icon,mmc_unbox_integer,modelica_integer_min)
@@ -86,7 +86,7 @@ boxptr_binOp(boxptr_realAdd,mmc_mk_rcon,mmc_unbox_real,+)
8686
boxptr_binOp(boxptr_realSub,mmc_mk_rcon,mmc_unbox_real,-)
8787
boxptr_binOp(boxptr_realMul,mmc_mk_rcon,mmc_unbox_real,*)
8888
boxptr_binOp(boxptr_realDiv,mmc_mk_rcon,mmc_unbox_real,/)
89-
boxptr_binFn(boxptr_realMod,mmc_mk_rcon,mmc_unbox_real,modelica_mod_real)
89+
boxptr_binFn(boxptr_realMod,mmc_mk_rcon,mmc_unbox_real,modelica_real_mod)
9090
boxptr_binFn(boxptr_realPow,mmc_mk_rcon,mmc_unbox_real,pow)
9191
boxptr_binFn(boxptr_realMin,mmc_mk_rcon,mmc_unbox_real,modelica_real_min)
9292
boxptr_binFn(boxptr_realMax,mmc_mk_rcon,mmc_unbox_real,modelica_real_max)

SimulationRuntime/c/util/utility.h

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,6 @@ static inline modelica_real modelica_div(modelica_real x, modelica_real y)
9090
return (modelica_real)((modelica_integer)(x/y));
9191
}
9292

93-
94-
/* fmod in math.h does not work in the same way as mod defined by modelica, so
95-
* we need to define our own mod. */
96-
static inline modelica_real modelica_mod_real(modelica_real x, modelica_real y)
97-
{
98-
return (x - (floor(x/y) * y));
99-
}
100-
101-
static inline modelica_integer modelica_mod_integer(modelica_integer x, modelica_integer y)
102-
{
103-
return x % y;
104-
}
105-
106-
10793
static inline modelica_integer modelica_integer_min(modelica_integer x,modelica_integer y)
10894
{
10995
return (x < y) ? x : y;
@@ -143,4 +129,23 @@ extern modelica_string OpenModelica_uriToFilename_impl(threadData_t *threadData,
143129
#define OpenModelica__uriToFilename(URI) OpenModelica_uriToFilename(URI)
144130
extern void OpenModelica_updateUriMapping(threadData_t *threadData, void *namesAndDirs);
145131

132+
static inline modelica_real modelica_real_mod(modelica_real x, modelica_real y)
133+
{
134+
return x-floor(x/y)*y;
135+
}
136+
137+
static inline modelica_integer modelica_integer_mod(modelica_integer x, modelica_integer y)
138+
{
139+
modelica_integer res = x%y;
140+
return res < 0 ? res+y : res /* % returns the remainder, which might be negative */;
141+
}
142+
143+
#if defined(OMC_BOOTSTRAPPING_STAGE_1) || defined(OMC_BOOTSTRAPPING_STAGE_2)
144+
#define modelica_mod_real modelica_real_mod
145+
static inline modelica_integer modelica_mod_integer(modelica_integer x, modelica_integer y)
146+
{
147+
return x%y;
148+
}
149+
#endif
150+
146151
#endif

0 commit comments

Comments
 (0)