mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-01-16 05:33:25 +00:00
Make volatile loads from IO/softswitches access exactly the byte(s) specified.
Previously, one-byte loads were typically done by reading a 16-bit value and then masking off the upper 8 bits. This is a problem when accessing softswitches or slot IO locations, because reading the subsequent byte may have some undesired effect. Now, ORCA/C will do an 8-bit read for such cases, if the volatile qualifier is used. There were also a couple optimizations that could occasionally result in not all the bytes of a larger value actually being read. These are now disabled for volatile loads that may access softswitches or IO. These changes should make ORCA/C more suitable for writing low-level software like device drivers.
This commit is contained in:
parent
21f266c5df
commit
daff1754b2
@ -349,11 +349,12 @@
|
||||
{ }
|
||||
{ pc_ind - load indirect }
|
||||
{ }
|
||||
{ Gen1t (pc_ind, disp, type) }
|
||||
{ Gen2t (pc_ind, volatile, disp, type) }
|
||||
{ }
|
||||
{ A value of type TYPE is loaded from DISP bytes past the }
|
||||
{ address that is on the evaluation stack. The address is }
|
||||
{ removed from the stack and replaced with the value. }
|
||||
{ VOLATILE is non-zero for a volatile load, or 0 otherwise. }
|
||||
{ }
|
||||
{ }
|
||||
{ pc_ior - logical or }
|
||||
|
6
DAG.pas
6
DAG.pas
@ -1414,7 +1414,8 @@ case op^.opcode of {check for optimizations of this node}
|
||||
PeepHoleOptimization(opv);
|
||||
end; {if}
|
||||
end {else if}
|
||||
else if op^.left^.opcode in [pc_lod,pc_ldo,pc_ind] then begin
|
||||
else if (op^.left^.opcode in [pc_lod,pc_ldo]) or
|
||||
((op^.left^.opcode = pc_ind) and (op^.left^.r = 0)) then begin
|
||||
if fromtype.optype in [cgWord,cgUWord] then
|
||||
if totype.optype in [cgByte,cgUByte,cgWord,cgUWord] then begin
|
||||
op^.left^.optype := totype.optype;
|
||||
@ -1452,7 +1453,8 @@ case op^.opcode of {check for optimizations of this node}
|
||||
with op^.left^ do
|
||||
if opcode in [pc_slr,pc_vsr] then
|
||||
if right^.opcode = pc_ldc then
|
||||
if left^.opcode in [pc_lod,pc_ldo,pc_ind] then begin
|
||||
if (left^.opcode in [pc_lod,pc_ldo]) or
|
||||
((left^.opcode = pc_ind) and (left^.r = 0)) then begin
|
||||
lq := right^.lval;
|
||||
if long(lq).msw = 0 then
|
||||
if long(lq).lsw in [8,16,24] then begin
|
||||
|
@ -2756,6 +2756,7 @@ var
|
||||
et: baseTypeEnum; {temp storage for a base type}
|
||||
i: integer; {loop variable}
|
||||
isString: boolean; {was the ? : a string?}
|
||||
isVolatile: boolean; {is this a volatile op?}
|
||||
lType: typePtr; {type of operands}
|
||||
kind: typeKind; {temp type kind}
|
||||
size: longint; {size of an array element}
|
||||
@ -3146,7 +3147,7 @@ var
|
||||
Gen2t(pc_lbf, bitDisp, bitSize, tp);
|
||||
end {if}
|
||||
else
|
||||
Gen1t(pc_ind, 0, tp);
|
||||
Gen2t(pc_ind, ord(tqVolatile in expressionType^.qualifiers), 0, tp);
|
||||
if pc_l in [pc_lli,pc_lld] then
|
||||
if expressionType^.cType in [ctBool,ctFloat,ctDouble,ctLongDouble,
|
||||
ctComp] then begin
|
||||
@ -3724,6 +3725,7 @@ case tree^.token.kind of
|
||||
Gen2t(pc_lod, t1, 0, cgULong);
|
||||
Gen2t(pc_lod, t1, 0, cgULong);
|
||||
lType := expressionType^.pType;
|
||||
isVolatile := tqVolatile in lType^.qualifiers;
|
||||
if isBitField then begin
|
||||
if unsigned then
|
||||
Gen2t(pc_lbu, bitDisp, bitSize, lType^.baseType)
|
||||
@ -3731,9 +3733,9 @@ case tree^.token.kind of
|
||||
Gen2t(pc_lbf, bitDisp, bitSize, lType^.baseType);
|
||||
end {if}
|
||||
else if lType^.kind = pointerType then
|
||||
Gen1t(pc_ind, 0, cgULong)
|
||||
Gen2t(pc_ind, ord(isVolatile), 0, cgULong)
|
||||
else
|
||||
Gen1t(pc_ind, 0, lType^.baseType);
|
||||
Gen2t(pc_ind, ord(isVolatile), 0, lType^.baseType);
|
||||
end; {else}
|
||||
if tqConst in lType^.qualifiers then
|
||||
Error(93);
|
||||
@ -4481,13 +4483,14 @@ case tree^.token.kind of
|
||||
else if lType^.kind = pointerType then
|
||||
lType := lType^.pType;
|
||||
expressionType := lType;
|
||||
isVolatile := tqVolatile in lType^.qualifiers;
|
||||
if lType^.kind = scalarType then
|
||||
if lType^.baseType = cgVoid then
|
||||
Gen1t(pc_ind, 0, cgULong)
|
||||
Gen2t(pc_ind, ord(isVolatile), 0, cgULong)
|
||||
else
|
||||
Gen1t(pc_ind, 0, lType^.baseType)
|
||||
Gen2t(pc_ind, ord(isVolatile), 0, lType^.baseType)
|
||||
else if lType^.kind = pointerType then
|
||||
Gen1t(pc_ind, 0, cgULong)
|
||||
Gen2t(pc_ind, ord(isVolatile), 0, cgULong)
|
||||
else if not
|
||||
((lType^.kind in [functionType,arrayType,structType,unionType])
|
||||
or ((lType^.kind = definedType) and {handle const struct/union}
|
||||
@ -4513,6 +4516,7 @@ case tree^.token.kind of
|
||||
size := 0;
|
||||
end; {else}
|
||||
kind := expressionType^.kind;
|
||||
isVolatile := tqVolatile in expressionType^.qualifiers;
|
||||
if kind = scalarType then begin
|
||||
et := expressionType^.baseType;
|
||||
if isBitField then begin
|
||||
@ -4524,12 +4528,12 @@ case tree^.token.kind of
|
||||
Gen2t(pc_lbf, bitDisp, bitSize, et);
|
||||
end {if}
|
||||
else
|
||||
Gen1t(pc_ind, long(size).lsw, et);
|
||||
Gen2t(pc_ind, ord(isVolatile), long(size).lsw, et);
|
||||
end {if}
|
||||
else if kind = pointerType then
|
||||
Gen1t(pc_ind, long(size).lsw, cgULong)
|
||||
Gen2t(pc_ind, ord(isVolatile), long(size).lsw, cgULong)
|
||||
else if kind = enumType then
|
||||
Gen1t(pc_ind, long(size).lsw, cgWord)
|
||||
Gen2t(pc_ind, ord(isVolatile), long(size).lsw, cgWord)
|
||||
else if size <> 0 then
|
||||
Gen1t(pc_inc, long(size).lsw, cgULong);
|
||||
end {if}
|
||||
|
23
Gen.pas
23
Gen.pas
@ -2923,6 +2923,7 @@ var
|
||||
lQuad: quadType; {requested quad address type}
|
||||
optype: baseTypeEnum; {op^.optype}
|
||||
q: integer; {op^.q}
|
||||
volatileByte: boolean; {is this a volatile byte access?}
|
||||
|
||||
begin {GenInd}
|
||||
optype := op^.optype;
|
||||
@ -3068,22 +3069,36 @@ case optype of
|
||||
cgByte,cgUByte,cgWord,cgUWord: begin
|
||||
GetPointer(op^.left);
|
||||
if gLong.where = inPointer then begin
|
||||
if q = 0 then
|
||||
volatileByte := (op^.r <> 0) and (optype in [cgByte,cgUByte]);
|
||||
if q = 0 then begin
|
||||
if volatileByte then
|
||||
GenNative(m_sep, immediate, 32, nil, 0);
|
||||
if gLong.fixedDisp then
|
||||
GenNative(m_lda_indl, direct, gLong.disp, nil, 0)
|
||||
else
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0)
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
if volatileByte then
|
||||
GenNative(m_rep, immediate, 32, nil, 0);
|
||||
end {if}
|
||||
else
|
||||
if gLong.fixedDisp then begin
|
||||
if volatileByte then
|
||||
GenNative(m_sep, immediate, 32, nil, 0);
|
||||
GenNative(m_ldy_imm, immediate, q, nil, 0);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0)
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
if volatileByte then
|
||||
GenNative(m_rep, immediate, 32, nil, 0);
|
||||
end {if}
|
||||
else begin
|
||||
GenImplied(m_tya);
|
||||
GenImplied(m_clc);
|
||||
GenNative(m_adc_imm, immediate, q, nil, 0);
|
||||
GenImplied(m_tay);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0)
|
||||
if volatileByte then
|
||||
GenNative(m_sep, immediate, 32, nil, 0);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
if volatileByte then
|
||||
GenNative(m_rep, immediate, 32, nil, 0);
|
||||
end; {else}
|
||||
end {if}
|
||||
else if gLong.where = localAddress then begin
|
||||
|
Loading…
x
Reference in New Issue
Block a user